Java实现Word转PDF及PDF转图片
在日常开发中,我们经常需要将文件操作,比如:
- 根据模板填充word
- word文档中插入图片
- Word文档转换为PDF格式
- 将PDF文件转换为图片。
这些转换可以帮助我们在不同的场景下展示或处理文档内容。下面,我将介绍如何使用Java来实现这两个功能。
要实现模板填充word,我们可以使用Apache POI和poi-tl库。Apache POI用于读取Word文档内容,而poi-tl则用于填充模板文件。
1. 添加依赖
<!-- 模板填充word 注意 poi-tl 与 pio 两个版本号要相互对应,不然会抛异常版本不一致 -->
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.2</version>
</dependency>
<!-- word 转 pdf -->
<dependency>
<groupId>com.documents4j</groupId>
<artifactId>documents4j-local</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>com.documents4j</groupId>
<artifactId>documents4j-transformer-msoffice-word</artifactId>
<version>1.0.3</version>
</dependency>
<!-- pdf转图片 -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.25</version>
</dependency>
<!-- 其他工具 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
2. 编写转换代码
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.PictureType;
import com.deepoove.poi.data.Pictures;
import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
/**
* @author lqf
* @date 2024/04/28 11:09
*/
public class startDemo001 {
public static void main(String[] args) throws IOException {
String filePath = "D:\\data\\muban2.docx";
String targetPath = "D:\\data\\do1.docx";
Map<String,Object> map = new HashMap<>();
map.put("tile", "使用Word模板");
map.put("details", "打开Word2010文档窗口,依次单击“文件”→“新建”按钮");
map.put("time", "2024-04-28");
// 添加网络图片
URL url = new URL("https://img-blog.csdnimg.cn/direct/1e85d3ac1f64415bbc965cba7ba1f8d9.png");
//打开连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置请求方式为"GET"
conn.setRequestMethod("GET");
//超时响应时间为10秒
conn.setConnectTimeout(10 * 1000);
//通过输入流获取图片数据 如果是本地图片,将网络请求换成本地文件流即可
InputStream is = conn.getInputStream();
PictureRenderData pictureRenderData = Pictures.ofStream(is, PictureType.PNG)
.size(100, 50).create();
map.put("img", pictureRenderData);
writForTemplate(filePath, targetPath, map);
String pdfPath = "D:\\data\\do1.pdf";
wordConvertPdf(targetPath, pdfPath);
// 一个pdf可能会输出多个图片,所以这儿是图片文件夹路径
pdfFileToImages(pdfPath, "D:\\data");
}
/**
* 在Word模版中写入指定内容
* @param filePath 模版文件地址
* @param targetPath 生成文件的目标地址
* @param map 填充内容
* @throws IOException
*/
public static void writForTemplate(String filePath, String targetPath, Map<String,Object> map) throws IOException {
XWPFTemplate template = XWPFTemplate.compile(filePath).render(map);
template.writeAndClose(Files.newOutputStream(Paths.get(targetPath)));
}
/**
*
* @param wordPath word 文件路径
* @param pdfPath pdf 输出路径
* @throws IOException
*/
public static void wordConvertPdf(String wordPath, String pdfPath) throws IOException {
InputStream wordInputStream = Files.newInputStream(Paths.get(wordPath));
// 转成 pdf
OutputStream outputStream = Files.newOutputStream(Paths.get(pdfPath));
IConverter converter = LocalConverter.builder().build();
converter.convert(wordInputStream).as(DocumentType.DOCX).to(outputStream).as(DocumentType.PDF).execute();
converter.shutDown();
}
/**
* pdf 转 png 图片
* @param filePath pdf文件路径
* @param imgDirPath 存储图片文件夹路径,一个pdf可能会输出多个图片,所以这儿是图片文件夹路径
*/
public static void pdfFileToImages(String filePath, String imgDirPath) {
try {
File pdfFile = new File(filePath);
String name = pdfFile.getName();
String imgName = name.substring(0, name.indexOf("."));
PDDocument pd = PDDocument.load(pdfFile);
PDFRenderer pdfRenderer = new PDFRenderer(pd);
for (int page = 0; page < pd.getNumberOfPages(); ++page) {
BufferedImage image = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
//将图片数据保存为PNG格式文档
File file= new File(imgDirPath + "\\" + imgName + "_" + page + ".png");
if (file.exists() ) {
boolean newFile = file.createNewFile();
}
ImageIO.write(image, "png", file);
System.out.println(file.getAbsolutePath());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
3. 测试使用的 word 模板内容
3.1 {{tile}}: 双大括号为文本占位符
3.2 {{@img}}: 双大括号中加上@为图片占位符
3.3 示例:
{{tile}}
在Word2010中使用模板创建文档的方法:
第1步,{{details}}。
第2步,在打开的“新建”面板中,用户可以单击“博客文章”、“书法字帖”等Word2010自带的模板创建文档,还可以单击Office网站提供的“名片”、“日历”等在线模板。例如单击“样本模板”选项。
第3步,打开样本模板列表页,单击合适的模板后,在“新建”面板右侧选中“文档”或“模板”单选框(本例选中“文档”选项),然后单击“创建”按钮。
第4步,打开使用选中的模板创建的文档,用户可以在该文档中进行编辑。
小提示:除了使用Word2010已安装的模板,用户还可以使用自己创建的模板和Office网站提供的模板。在下载Office网站提供的模板时,Word2010会进行正版验证,非正版的Word2010版本无法下载Office Online提供的模板。
文档时间{{time}}
展示图片{{@img}}
4. 测试使用的网络图片
5. 代码运行结果
生成的word文档:
生成的pdf:
生成的图片:
亲测格式正常,数据正常