<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.6.3</version>
</dependency>
//XWPFDocument 转 MultipartFile(MockMultipartFile),则需要导入
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.6.RELEASE</version>
<scope>compile</scope>
</dependency>
import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.word.WordExportUtil;
import com.xxiang.digital_cloud.entity.vo.ProjectDailyVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Slf4j
public class WordUtils {
/**
* 图片大小路径设置
* 默认长宽是200
* @return
*/
public static ImageEntity pictureSize(String s){
ImageEntity imageEntity = new ImageEntity();
imageEntity.setHeight(200);
imageEntity.setWidth(200);
imageEntity.setUrl(s);
imageEntity.setType(ImageEntity.URL);
return imageEntity;
}
/**
* word提交
* @return
*/
public static XWPFDocument wordSubmit(String wordUrl, String wordTemplateUrl, Map<String, Object> map){
XWPFDocument doc = null;
try {
doc = WordExportUtil.exportWord07(wordUrl, map);
FileOutputStream fos = new FileOutputStream(wordTemplateUrl);
doc.write(fos);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
return doc;
}
/**
* 多个word数据合并到一个word中提交
* @param wordUrl
* @param wordTemplateUrl
* @param list
* @return
*/
public static XWPFDocument moreWordSubmit(String wordUrl, String wordTemplateUrl, List<Map<String, Object>> list){
XWPFDocument doc = null;
try {
doc = WordExportUtil.exportWord07(wordUrl, list);
FileOutputStream fos = new FileOutputStream(wordTemplateUrl);
doc.write(fos);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
return doc;
}
/**
* 将对象转换成map
* @param obj
* @return
* @throws Exception
*/
public static Map<String, Object> objectToMap(Object obj) throws Exception {
if (obj == null) {
return null;
}
Map<String, Object> map = new HashMap<String, Object>();
Field[] declaredFields = obj.getClass().getDeclaredFields();
for (Field field : declaredFields) {
field.setAccessible(true);
map.put(field.getName(), field.get(obj));
}
return map;
}
/**
* 删除临时文件
*
*/
public static void delFileWord(String filePathUrl, String FileName){
File file = new File(filePathUrl+FileName);
File file1 = new File(filePathUrl);
file.delete();
file1.delete();
}
/**
* XWPFDocument 转 MultipartFile(MockMultipartFile)
*
* @param document 文档对象
* @param fileName 文件名
* @return
*/
public static MultipartFile xwpfDocumentToMockMultipartFile(XWPFDocument document, String fileName) {
try {
String contentType = "text/plain";
ByteArrayOutputStream bos = new ByteArrayOutputStream();
document.write(bos);
//XWPFDocument 转 byte[]
byte[] barray = bos.toByteArray();
//byte[] 转 InputStream
InputStream is = new ByteArrayInputStream(barray);
//InputStream 转 MultipartFile
MultipartFile multipartFile = new MockMultipartFile(fileName, fileName, contentType, is);
return multipartFile;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* word文件合并
* @param wordList
* @return
* @throws Exception
*/
public static XWPFDocument mergeWord(List<XWPFDocument> wordList) throws Exception{
if (CollectionUtils.isEmpty(wordList)) {
throw new RuntimeException("待合并的word文档list为空");
}
XWPFDocument doc = wordList.get(0);
int size = wordList.size();
if (size > 1) {
doc.createParagraph().setPageBreak(true);
for (int i = 1; i < size; i++) {
// 从第二个word开始合并
XWPFDocument nextPageDoc = wordList.get(i);
// 最后一页不需要设置分页符
if (i != (size-1)) {
nextPageDoc.createParagraph().setPageBreak(true);
}
appendBody(doc, nextPageDoc);
}
}
return doc;
}
private static void appendBody(XWPFDocument src, XWPFDocument append) throws Exception {
CTBody src1Body = src.getDocument().getBody();
CTBody src2Body = append.getDocument().getBody();
List<XWPFPictureData> allPictures = append.getAllPictures();
// 记录图片合并前及合并后的ID
Map<String,String> map = new HashMap<>();
for (XWPFPictureData picture : allPictures) {
String before = append.getRelationId(picture);
//将原文档中的图片加入到目标文档中
String after = src.addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG);
map.put(before, after);
}
appendBody(src1Body, src2Body,map);
}
private static void appendBody(CTBody src, CTBody append, Map<String,String> map) throws Exception {
XmlOptions optionsOuter = new XmlOptions();
optionsOuter.setSaveOuter();
String appendString = append.xmlText(optionsOuter);
String srcString = src.xmlText();
String prefix = srcString.substring(0,srcString.indexOf(">")+1);
String mainPart = srcString.substring(srcString.indexOf(">")+1,srcString.lastIndexOf("<"));
String sufix = srcString.substring( srcString.lastIndexOf("<") );
String addPart = appendString.substring(appendString.indexOf(">") + 1, appendString.lastIndexOf("<"));
if (map != null && !map.isEmpty()) {
//对xml字符串中图片ID进行替换
for (Map.Entry<String, String> set : map.entrySet()) {
addPart = addPart.replace(set.getKey(), set.getValue());
}
}
//将两个文档的xml内容进行拼接
CTBody makeBody = CTBody.Factory.parse(prefix+mainPart+addPart+sufix);
src.set(makeBody);
}
/**
* 流式分组
* @param dailyVoList
* @return
*/
public static List<List<ProjectDailyVo>> objectMap(List<ProjectDailyVo> dailyVoList){
Map<String, List<ProjectDailyVo>> collect = dailyVoList.stream().collect(Collectors.groupingBy(ProjectDailyVo::getPhaseCombinationId));
List<List<ProjectDailyVo>> list = new ArrayList<>();
for (String key:collect.keySet()
) {
List<ProjectDailyVo> projectDailyVos = collect.get(key);
list.add(projectDailyVos);
}
return list;
}
public static boolean deleteDir(String path) {
File file = new File(path);
if (!file.exists()) {//判断是否待删除目录是否存在
return false;
}
String[] content = file.list();//取得当前目录下所有文件和文件夹
for (String name : content) {
File temp = new File(path, name);
if (temp.isDirectory()) {//判断是否是目录
deleteDir(temp.getAbsolutePath());//递归调用,删除目录里的内容
temp.delete();//删除空目录
} else {
if (!temp.delete()) {//直接删除文件
System.err.println("Failed to delete " + name);
}
}
}
return true;
}
}