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));// 转成 pdfOutputStream 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:
生成的图片:
亲测格式正常,数据正常