import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.concurrent.TimeUnit;
/**
* 处理Word工具类
*
* @author king
* @since 2021-03-12 10:32
*/
public class WordUtil {
private static final Logger logger = LoggerFactory.getLogger(WordUtil.class);
private static final String FILE_SUFFIX = ".pdf";
private static final IConverter converter = LocalConverter.builder()
.workerPool(5, 10, 2, TimeUnit.SECONDS)
.processTimeout(5, TimeUnit.SECONDS)
.build();
/**
* word转pdf方法
*
* @param docxInputStream word文件流
* @param localPath 资源存储路径
* @return
*/
public static String wordToPdf(InputStream docxInputStream, String localPath, String fileName) {
// 拼接后的文件名
fileName = fileName + FILE_SUFFIX;
String path = localPath + File.separator + fileName;
//pdf文件的路径
File outputFile = new File(path);
try (OutputStream outputStream = new FileOutputStream(outputFile)) {
// IConverter converter = LocalConverter.builder().build();
converter.convert(docxInputStream).as(DocumentType.DOCX).to(outputStream).as(DocumentType.PDF).execute();
} catch (IOException e) {
logger.error("word转pdf出现异常:{}:{}", e.getMessage(), e);
}
return path;
}
/**
* word转pdf方法
*
* @param wordPath word存放路径
* @param localPath 资源存储路径
* @return
*/
public static String wordToPdf(String wordPath, String localPath, String fileName) {
//word的路径
File inputWord = new File(wordPath);
// 拼接后的文件名
fileName = fileName + FILE_SUFFIX;
String path = localPath + File.separator + fileName;
//pdf文件的路径
File outputFile = new File(path);
try (InputStream docxInputStream = new FileInputStream(inputWord);
OutputStream outputStream = new FileOutputStream(outputFile)) {
IConverter converter = LocalConverter.builder().build();
converter.convert(docxInputStream).as(DocumentType.DOCX).to(outputStream).as(DocumentType.PDF).execute();
converter.kill();
} catch (IOException e) {
logger.error("word转pdf出现异常:{}:{}", e.getMessage(), e);
}
return path;
}
}
示例
通过将已准备好的word模板文件,进行数据填充(这里用的是easypoi),然后将替换后的word文件转为pdf文件
/**
* Document key
*/
public static final String PROPERTY_KEY = "javax.xml.parsers.DocumentBuilderFactory";
/**
* Document value
*/
public static final String PROPERTY_VALUE = "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl";
System.setProperty(PROPERTY_KEY, PROPERTY_VALUE);
// 替换word模板中的数据
byte[] wordBytes = replaceDocxData(filePath, mapObject);
// 将二进制数组转换成io流
try (InputStream inputStream = new ByteArrayInputStream(wordBytes)) {
// word转pdf
String toPdfPath = WordUtil.wordToPdf(inputStream, this.getWordTempPath(), fileName);
if (StringUtils.isNotBlank(toPdfPath)) {
try (InputStream pdfInputStream = new FileInputStream(new File(toPdfPath))) {
body = IOUtils.toByteArray(pdfInputStream);
}
}
}
/**
* 替换word模板中的数据
*
* @param filePath 源word模板路径 // * @param toPath word模板替换后存储路径
* @param map 模板内容
*/
private byte[] replaceDocxData(String filePath, Map<String, Object> map) throws FileNotFoundException {
// 控制处理,防止因空数据导致数据不替换
if (map != null) {
for (Entry<String, Object> entry : map.entrySet()) {
if (ObjectUtils.isEmpty(entry.getValue())) {
map.put(entry.getKey(), " ");
}
}
}
File file = new File(filePath);
byte[] doc = new byte[0];
// 文件不存在返回错误信息
if (!file.exists() || !file.isFile()) {
throw new FileNotFoundException();
}
try {
doc = exportWord(filePath, map);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return doc;
}
public static byte[] exportWord(String templateWordPath, Map<String, Object> dataMap) throws Exception {
XWPFDocument document = WordExportUtil.exportWord07(templateWordPath, dataMap);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
document.write(bos);
return bos.toByteArray();
}
easypoi maven
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.2.0</version>
</dependency>