参考自
https://blog.csdn.net/weixin_50638065/article/details/133958393
依赖包
最下面的两个包肯定需要的,其他的有几个不需要的,自己试着删一下,用不了这么多
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
<!--poi-tl-->
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.1</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.20</version>
</dependency>
<dependency>
<groupId>com.aspose.words</groupId>
<artifactId>aspose-words-jdk16</artifactId>
<version>15.8.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.15</version>
</dependency>
word文档格式
-
我用的是docx格式,文字替换使用的替换符为 美元符号+大括号,中间是传入的参数名;例:
${year}年${month}月${day}日
-
图片的替换方式为使用“word的标签格式‘;操作步骤为:
- 先鼠标点击想要插入图片的位置;
- 菜单栏点击--插入--书签--输入书签名--点击添加;OK了,书签名就是图片的替换文本,也就是代码中map的key;
这里使用apache-aspose去除pdf的水印
在resources目录下加入License.xml配置文件
<!--报表打印,去水印-->
<License>
<Data>
<Products>
<Product>Aspose.Total for Java</Product>
<Product>Aspose.Words for Java</Product>
</Products>
<EditionType>Enterprise</EditionType>
<SubscriptionExpiry>20991231</SubscriptionExpiry>
<LicenseExpiry>20991231</LicenseExpiry>
<SerialNumber><!-- 自己百度找吧 --></SerialNumber>
</Data>
<Signature>
<!-- 自己百度找吧 -->
</Signature>
</License>
word插入文字、图片、转换成pdf的base64
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import java.util.List;
import java.util.Map;
/**
* 获取原文件,并将其生成pdf的base64
* @param map 需要插入的文本 {"text1":"asdf","text2":"233"} text1和text2就是插入的文本,在word中用 ${text1};
* @param map1 需要插入的图片 {"pic1":"base64"} pic1就是插入word中的标签,值是图片的base64
* @param base64 原docx文件的base64
* @return
*/
public static String searchAndReplace(Map<String, Object> map, Map<String, Object> map1, String base64) {
// 获取原docx文件
byte[] decodedBytes = Base64.getDecoder().decode(base64.replaceAll("[^A-Za-z0-9+/=]", ""));
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decodedBytes)){
XWPFDocument document = new XWPFDocument(byteArrayInputStream);
// 替换文字与图片标签
replaceInPara1(document, map, map1);
// 生成pdf的base64
return docxConvertPdf(document);
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// document.write(out);
// byte[] bytes = out.toByteArray();
// out.close();
// return Base64.getEncoder().encodeToString(bytes);
} catch (Exception e) {
// XXXXXXX
}
return null;
}
/**
* 替换段落里面的变量
* @param doc 要替换的文档
* @param params 参数
*/
public static void replaceInPara1(XWPFDocument doc, Map<String, Object> params, Map<String, Object> params1) {
for (XWPFParagraph para : doc.getParagraphs()) {
replaceInPara(para, params);
}
for (XWPFParagraph para : doc.getParagraphs()) {
replaceInBook(para, params1);
}
}
/**
* 替换段落里面的文字
*
* @param paragraph 要替换的段落
* @param params 参数
*/
private static void replaceInPara(XWPFParagraph paragraph, Map<String, Object> params) {
List<XWPFRun> runs = paragraph.getRuns();
for (int i = 0; i < runs.size(); i++) {
//获取字符
String text0 = runs.get(i).getText(runs.get(i).getTextPosition());
if (text0 != null && text0.contains("$")) {
//包含占位符的字符缓存
StringBuilder cache = new StringBuilder(text0);
int endIndex = 0;
boolean contains = text0.contains("}");
//同一个run中是否包含占位符
if (!contains) {
int j = i + 1;
for (; j < runs.size(); j++) {
String text1 = runs.get(j).getText(runs.get(j).getTextPosition());
if (text1 == null) {
continue;
}
cache.append(text1);
if (text1.contains("}")) {
endIndex = j;
break;
}
}
}
if (contains || endIndex != 0) {
//处理替换
String s = cache.toString();
for (Map.Entry<String, Object> entry : params.entrySet()) {
String k = entry.getKey();
String v = entry.getValue().toString();
if (s.contains("${" + k + "}")) {
String replace = s.replace("${" + k + "}", v);
runs.get(i).setText(replace, 0);
for (int j = endIndex; j > i; j--) {
runs.get(j).setText("", 0);
}
break;
}
}
}
}
}
}
/**
* 替换段落里面的图片标签
*
* @param paragraph 要替换的段落
* @param params 参数
*/
private static void replaceInBook(XWPFParagraph paragraph, Map<String, Object> params) {
CTP ctp = paragraph.getCTP();
for (int dwI = 0; dwI < ctp.sizeOfBookmarkStartArray(); dwI++) {
CTBookmark bookmark = ctp.getBookmarkStartArray(dwI);
if (!params.containsKey(bookmark.getName())) continue;
try (InputStream ins = (InputStream) params.get(bookmark.getName())){
XWPFRun run = paragraph.createRun();
//bus.png为鼠标在word里选择图片时,图片显示的名字,100,100则为像素单元,根据实际需要的大小进行调整即可。
run.addPicture(ins, XWPFDocument.PICTURE_TYPE_PNG, "tutu.png,", Units.toEMU(56), Units.toEMU(35));
} catch (InvalidFormatException | IOException e) {
// XXXXXX
}
}
}
/**
* docx转换pdf
*/
public static String docxConvertPdf(XWPFDocument doc){
// 写入文档到输出流
try (ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream outPdf = new ByteArrayOutputStream()){
doc.write(out);
// 将输出流转换为字节数组
byte[] docBytes = out.toByteArray();
// 将字节数组转换为输入流
try(InputStream inputStream = new ByteArrayInputStream(docBytes)){
if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
log.error("向docx文件中插入图片时失败");
BusiExcUtil.dataIsTrueEx(true, "验证License失败!");
}
com.aspose.words.Document document = new com.aspose.words.Document(inputStream);
document.save(outPdf, SaveFormat.PDF);
byte[] byteArray = outPdf.toByteArray();
return Base64.getEncoder().encodeToString(byteArray);
} catch (Exception e) {
log.error("docx转换pdf时失败", e);
BusiExcUtil.dataIsTrueEx(true, "docx转换pdf时失败!");
}
} catch (IOException e) {
log.error("docx转换pdf时失败", e);
BusiExcUtil.dataIsTrueEx(true, "docx转换pdf时失败!");
}
return null;
}
/**
* 验证且去除pdf水印
* @return
*/
public static boolean getLicense() {
try (InputStream is = DocxToPdf.class.getClassLoader().getResourceAsStream("License.xml")){
License license = new License();
license.setLicense(is);
return true;
} catch (Exception e) {
log.error("验证且去除pdf水印失败", e);
}
return false;
}
标签:word,org,poi,插入,params,pdf,apache,import
From: https://www.cnblogs.com/xy20211005/p/18205800