18.java word,pdf等操作
Poi
依赖
<poi.version>5.2.5</poi.version>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
word读取,简单替换
package com.chiyi.poi.word;
import org.apache.poi.xwpf.usermodel.*;
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author wakeleo
* @description 按照模板, 替换word文档
*/
public class DocPoi {
private String srcPath = "C:\\Users\\young\\Desktop\\二检合一证书报告模板.docx"; // 模板路径
private String outPath = "C:\\Users\\young\\Desktop\\123.docx"; // 输出路径
private String outPathPdf = "C:\\Users\\young\\Desktop\\123.aspose";
private Map param;
private XWPFDocument docTemplate;
private Pattern pattern = Pattern.compile("\\$\\{(.+?)}"); // 查找 ${}
public DocPoi() {
}
public DocPoi(Map param) {
this.param = param;
}
public DocPoi(String srcPath, Map param) {
this.srcPath = srcPath;
this.param = param;
}
// 0 读取表格
private XWPFDocument getDoc() {
try (InputStream fis = new FileInputStream(srcPath);) {
return new XWPFDocument(fis);
} catch (Exception e) {
e.printStackTrace();
System.out.println("读取文件错误:" + e.getMessage());
}
return null;
}
//1.1 读取段落
private void readParagraph(XWPFParagraph paragraph) {
for (XWPFRun run : paragraph.getRuns()) { // 获取一个run
String text = run.toString();
// String value = replaceColumn(text, table);
// if (value != null) {
// run.setText(value, 0); // 替换 原本的run
// }
}
}
// 1.2 读取表格
private void readTable(XWPFTable table) {
for (XWPFTableRow row : table.getRows()) { //获取一行
for (XWPFTableCell cell : row.getTableCells()) { // 获取一个单元格
//如果包含子表格,递归
if (cell.getTables() != null && cell.getTables().size() > 0) {
List<XWPFTable> childTables = cell.getTables();
for (XWPFTable childTable : childTables) {
readTable(childTable);
}
}
for (XWPFParagraph paragraph : cell.getParagraphs()) { // 如果是段落, 读取段落
readParagraph(paragraph);
}
}
}
}
// 1.3 替换字段
private String replaceColumn(String text, XWPFTable table) {
if (text.contains("${")) {
Matcher matcher = pattern.matcher(text);
if (matcher.find()) {
String key = matcher.group(1);
if (text.endsWith("List}")) {
// replaceList(table, key);
} else {
String value = param.get(key).toString(); // 要替换的内容
if (value != null) {
return text.replace("${" + key + "}", value);
}
}
}
}
return null;
}
//2. word文档读取
public Boolean geneDoc() {
return geneDoc(srcPath, param);
}
public Boolean geneDoc(String srcPath, Map param) {
docTemplate = getDoc(); // 读取word
if (docTemplate == null) {
return false;
}
System.out.println("=================1. 读取段落================");
List<XWPFParagraph> paragraphList = docTemplate.getParagraphs(); // 获取所有段落
for (XWPFParagraph paragraph : paragraphList) {
readParagraph(paragraph, null);
}
System.out.println("============2. 读取word中的表格========");
List<XWPFTable> tableList = docTemplate.getTables(); //获取所有表格
for (XWPFTable table : tableList) {
readTable(table);
}
//修改,写入
try (FileOutputStream fos = new FileOutputStream(outPath)) {
docTemplate.write(fos);
return true;
} catch (Exception e) {
e.printStackTrace();
System.out.println("写入错误" + e.getMessage());
}
return false;
}
public static void main(String[] args) throws IOException {
Map map = new HashMap<>();
map.put("method", "teeeeeeeeeeeeeeeee");
map.put("cerNum", "teeeeeeeeeeeeeeeee");
DocPoi docPoi = new DocPoi(map);
docPoi.geneDoc();
}
}
xdocreport
使用 freemarker
依赖
<xdocreport.version>2.0.2</xdocreport.version>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.core</artifactId>
<version>${xdocreport.version}</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.document</artifactId>
<version>${xdocreport.version}</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.template</artifactId>
<version>${xdocreport.version}</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.document.docx</artifactId>
<version>${xdocreport.version}</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.poi.xwpf.converter.pdf</artifactId>
<version>${xdocreport.version}</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId>
<version>${xdocreport.version}</version>
</dependency>
word模板填充
使用 xdocreport
package com.chiyi.poi.word;
import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import lombok.Data;
import org.apache.poi.xwpf.usermodel.*;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
/**
* @author wakeleo
* @description 按照模板, 填充 word 文档,
* 一对一替换: ${} ,
* 一对多 替换 ${abc.id} 原数据类似 list<User>
* 一对多,多列动态表格, 需要用到域设置
* - 格式 ${abc.id}
* - wps中,选中内容 -> 插入->文档部件->域 -> 邮件合并 -> 把这个追加到结尾 ${abc.id}
*
*/
public class DocFill {
private String srcPath = "C:\\Users\\young\\Desktop\\二检合一证书报告模板.docx"; // 模板路径
private String outPath;
private String srcSuffix = ".docx";
private Map param;
private XWPFDocument doc;
private Pattern pattern = Pattern.compile("\\$\\{(.+?)}"); // 查找 ${}
public DocFill() {
}
public DocFill(Map param) {
this.param = param;
}
public DocFill(String srcPath, Map param) {
this.srcPath = srcPath;
this.param = param;
}
public void setOutPath(){
srcSuffix= srcPath.substring(srcPath.indexOf("."));
outPath=srcPath.replace("."+srcSuffix, "_new."+srcSuffix);
}
/**
* 定义实体类
* 用于动态表格
* 模板中相关字段 属性需要 设置为域
*/
@Data
class ZhunBeiJieDuanList {
String createTime;
String content;
}
//2.生成 word
public void geneDoc(String srcPath, Map param) throws IOException, XDocReportException {
FileInputStream ins = new FileInputStream(srcPath);
//注册xdocreport实例并加载FreeMarker模板引擎
IXDocReport report = XDocReportRegistry.getRegistry().loadReport(ins, TemplateEngineKind.Freemarker);
//创建xdocreport上下文对象,用于存放具体数据
IContext context = report.createContext();
// 将map填充到 context, 其中列表要特殊处理,
param.forEach((k, v) -> {
String key = String.valueOf(k);
if (key.endsWith("List")) {
List<Map> coList = (List) v;
if ("zhunBeiJieDuanList".equals(key)) {
List<ZhunBeiJieDuanList> zhunBeiJieDuanList = (List<ZhunBeiJieDuanList>) v;
context.put(key, zhunBeiJieDuanList);
} else if ("xxx".equals(key)) {
}
} else {
context.put(key, v);
}
});
//创建字段元数据
FieldsMetadata fm = report.createFieldsMetadata();
//Word模板中的表格数据对应的集合类型
fm.load("zhunBeiJieDuanList", ZhunBeiJieDuanList.class, true);
fm.load("jieGuoBiDuiList", JieGuoBiDuiList.class, true);
//创建输出流
FileOutputStream out = new FileOutputStream(new File(outPath));
//写入
report.process(context, out);
}
public void geneDoc() throws IOException, XDocReportException {
geneDoc(srcPath, param);
}
//3. 测试
public static void main(String[] args) throws IOException, XDocReportException {
Map map = new HashMap<>();
map.put("cerNum", "teeeeeeeeeeeeeeeee");
map.put("zhunBeiJieDuanList", new ArrayList() {{
add(new HashMap() {{
put("createTime", "2024-01-23 10:30:58");
put("content", "开始");
}});
add(new HashMap() {{
put("createTime", "2024-01-23 10:36:35");
put("content", "完结");
}});
}});
// 调用
DocFill docPoi = new DocFill(map);
docPoi.geneDoc(); //生成 word
}
}
aspose-words
可以转很多,图片, pdf,epub,html之类的
word转pdf
参考: [https://blog.csdn.net/qq_35222232/article/details/129163200]
- 下载jar和 license
链接:https://pan.baidu.com/s/1m3fQRDsj8clJofpOeGOl-w?pwd=aspo
提取码:aspo
- 把两个jar文件放到 resource 目录下的lib目录,(lib不存在自己新建)
- 把 license.xml文件放到 resource目录下
- win可能要管理员运行idea
pom.xml
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>15.12.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/aspose-words-15.12.0-jdk16.jar</systemPath>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope> <!-- 在这个位置,这个选项打包时把本地system的jar也包括进来 -->
</configuration>
</plugin>
<plugins>
<build>
实现
import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import org.springframework.core.io.ClassPathResource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* @Description: word转pdf
* @Version: 1.0
*/
public class WordToPdf {
private static String pdfPath = "C:\\Users\\young\\Desktop\\123.pdf";
private static String wordPath = "C:\\Users\\young\\Desktop\\123.docx";
private static boolean license = false;
public static void main(String[] args) {
WordToPdf wordToPdf = new WordToPdf();
try {
wordToPdf.wordToPdf(wordPath, pdfPath);
} catch (Exception e) {
e.printStackTrace();
}
}
public String wordToPdf(String wordPath,String pdfPath) throws Exception {
FileOutputStream os = null;
try {
//凭证 不然切换后有水印
InputStream is = new ClassPathResource("/license.xml").getInputStream();
License aposeLic = new License();
aposeLic.setLicense(is);
license = true;
if (!license) {
System.out.println("License验证不通过...");
return null;
}
//生成一个空的PDF文件
File file = new File(pdfPath);
os = new FileOutputStream(file);
//要转换的word文件
Document doc = new Document(wordPath);
doc.save(os, SaveFormat.PDF);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
}
itextPdf
pdf加水印
pom.xml
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.2</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
实现
- 可添加文字水印或图片水印
package com.chiyi.poi.aspose;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* pdf加水印
* @Author: wakeleo
* @Description: 分为图片水印和文字水印
* @Version: 1.0
*/
public class PdfAddSign {
private static final String signPicPath = "C:\\Users\\young\\Desktop\\未命名文件.png"; // 水印图片路径
private static final String SIGNTEXT = "水印文字"; // 水印文字
private static PdfContentByte under;
/**
* 0.1 图片水印
*/
private static void pictureMark(PdfStamper stamp,int pageSize) throws DocumentException, IOException {
//水印图片
Image image = Image.getInstance(signPicPath);
for (int i = 1; i <= pageSize; i++) {
under = stamp.getUnderContent(i);// 获取指定页
image.setAbsolutePosition(100, 210);//设置水印位置
under.addImage(image); // 添加水印
}
}
/**
* 0.2 文字水印
*/
public static void textMark(PdfStamper stamp,int pageSize)throws Exception {
PdfGState gs = new PdfGState();
BaseFont font = BaseFont.createFont("STSong-Light","UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
gs.setFillOpacity(0.4f);// 设置透明度
for (int i = 1; i < pageSize; i++) {
under = stamp.getOverContent(i);
under.beginText();
under.setGState(gs);
under.setColorFill(BaseColor.DARK_GRAY); //水印颜色
under.setFontAndSize(font, 26); //字体和大小
under.showTextAligned(Element.ALIGN_CENTER,SIGNTEXT, 300, 300, 15); //居中,内容,坐标,角度,
under.endText();
}
System.out.println("PDF水印添加完成!");
}
/**
* 1. 添加水印
* @param srcFile File, 原pdf
* @param markType String,文字水印或图片水印
* @return 添加水印后的pdf路径
*/
private static String addTextMark(File srcFile,String markType) {
PdfReader reader = null;
PdfStamper stamp = null;
try {
File outFile = new File(srcFile.getParent(), "new_"+srcFile.getName());
// 获取pdfReader对象
reader = new PdfReader(srcFile.toString());
stamp = new PdfStamper(reader, new FileOutputStream(outFile));
PdfContentByte under;
// 获取pdf总页数
int pageSize = reader.getNumberOfPages();
if (pageSize == 0) {
return null;
}
// 添加水印
if (markType.equals("text")) {
textMark(stamp,pageSize);
}else if(markType.equals("picture")){
pictureMark(stamp,pageSize);
}
return outFile.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (stamp != null) {
stamp.close();
}
if (reader != null) {
reader.close();//关闭
}
} catch (Exception ex) {
ex.printStackTrace();
}
//删除生成的无水印pdf
// if (srcFile != null && srcFile.exists() && srcFile.isFile()) {
// srcFile.delete();
// }
}
return null;
}
public static void main(String[] args) {
System.out.println(addTextMark(new File("C:\\Users\\young\\Desktop\\abc.pdf"),"text"));
}
}

浙公网安备 33010602011771号