当前位置: 首页 > news >正文

实现将docx转成PDF

最近实现了一个将docx转成PDF的功能,这里来记录一下实现过程

我是参考这篇文章Java将Word转换成PDF的常用用法_java_脚本之家

实现步骤基本上是按照上面文档中描述的内容,把大象装冰箱一共就三步

1、导入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>wordToPDF</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.4.RELEASE</version></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.3.5</version><scope>compile</scope></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.6</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></dependencies></project>

2、增加日志的配置文件(这一步可以忽略)

application.yml


logging:config: classpath:log4j2.xml

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="INFO" monitorInterval="30"><Properties><property name="ALL_LOG_FILE_NAME">log/</property><!-- 输出日志的格式 --><property name="PATTERN">[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%M-%t] [%-5level] %logger{36}:%L - %msg%n</property></Properties><Appenders><!--这个输出控制台的配置 --><Console name="Console" target="SYSTEM_OUT"><!-- 控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) --><ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/><PatternLayout pattern="${PATTERN}"/></Console><RollingFile name="RollingFileAll"fileName="${ALL_LOG_FILE_NAME}/all.log"filePattern="${ALL_LOG_FILE_NAME}/all-%d{yyyy-MM-dd}-%i.log"><Filters><!--设置只输出级别为info的日志--><ThresholdFilter level="all"/></Filters><!--文件输出格式--><PatternLayout pattern="${PATTERN}"/><Policies><!--每天一个文件--><TimeBasedTriggeringPolicy interval="1" modulate="true"/><!--单个文件的大小--><SizeBasedTriggeringPolicy size="100 MB"/></Policies><!--设置保留的文件数据--><DefaultRolloverStrategy max="12"><!--删除的规则--><Delete basePath="${ALL_LOG_FILE_NAME}" maxDepth="2"><!--保存文件名--><IfFileName glob="all-*.log"/><!--保留天数--><IfLastModified age="30d"/></Delete></DefaultRolloverStrategy></RollingFile></Appenders><!--然后定义logger,只有定义了logger并引入的appender,appender才会生效--><loggers><!--过滤掉spring和mybatis的一些无用的DEBUG信息--><logger name="org.springframework" level="warn"/><logger name="org.mybatis" level="warn"/><logger name="org.apache.kafka" level="warn"/><root level="info"><appender-ref ref="Console"/><appender-ref ref="RollingFileAll"/></root></loggers>
</configuration>

3、核心代码

package com.youyou;import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.documents4j.api.DocumentType;
import com.documents4j.api.IConversionJobWithPriorityUnspecified;
import com.documents4j.api.IConversionJobWithSourceSpecified;
import com.documents4j.api.IConversionJobWithSourceUnspecified;
import com.documents4j.api.IConversionJobWithTargetUnspecified;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import lombok.extern.slf4j.Slf4j;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;@Slf4j
public class Documents4jUtil {public static void main(String[] args) throws FileNotFoundException {File file = FileUtil.touch("D:\\Desktop\\SIU测试工装使用方法2.pdf");try (InputStream inputStream = IoUtil.toStream(FileUtil.file("D:\\Desktop\\SIU测试工装使用方法.docx"));OutputStream outputStream = new FileOutputStream(file)) {convertWordToPdf(inputStream, outputStream);System.out.println("完成");} catch (IOException e) {e.printStackTrace();}}/*** word转pdf*/public static void convertWordToPdf(InputStream stream, OutputStream sourceOutput) {String os = System.getProperty("os.name").toLowerCase();log.info("convertWordToPdf 当前操作系统:{}", os);if (os.contains("win")) {// Windows操作系统windowsWordToPdf(stream, sourceOutput);} else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {// Unix/Linux/Mac操作系统linuxWordToPdf(stream, sourceOutput);} else {// 未知操作系统throw new RuntimeException("不支持当前操作系统转换文档。");}}/*** 通过documents4j 实现word转pdf -- Windows 环境 需要有 Microsoft Office 服务*/public static void windowsWordToPdf(InputStream stream, OutputStream sourceOutput) {try {IConverter converter = LocalConverter.builder().build();IConversionJobWithSourceUnspecified convert = converter.convert(stream);IConversionJobWithSourceSpecified sourceSpecified = convert.as(DocumentType.DOCX);IConversionJobWithTargetUnspecified to = sourceSpecified.to(sourceOutput);IConversionJobWithPriorityUnspecified priorityUnspecified = to.as(DocumentType.PDF);boolean execute = priorityUnspecified.execute();log.info("转换结果:{}", execute);converter.shutDown();} catch (Exception e) {log.error("winWordToPdf windows环境word转换为pdf时出现异常:", e);}}/*** 通过libreoffice 实现word转pdf -- linux 环境 需要有 libreoffice 服务*/public static void linuxWordToPdf(InputStream stream, OutputStream sourceOutput) {// 创建临时文件File tempFile = createTempFileFromInputStream(stream);// 构建LibreOffice的命令行工具命令String command = "libreoffice6.4 --headless --invisible --convert-to pdf " + tempFile.getAbsolutePath() + " --outdir " + tempFile.getParent();// 执行转换命令try {if (!executeLinuxCmd(command)) {throw new IOException("转换失败");}readPdfFileToByteArrayOutputStream(tempFile, sourceOutput);} catch (Exception e) {log.error("ConvertWordToPdf: Linux环境word转换为pdf时出现异常:" + e + tempFile.getPath());// 清理临时文件tempFile.delete();} finally {File pdfFile = new File(tempFile.getParent(), tempFile.getName().replace(".docx", ".pdf"));//清理转换后的pdf文件pdfFile.delete();// 清理临时文件,无论是否成功转换tempFile.delete();}}/*** 执行命令行** @param cmd 命令行* @return* @throws IOException*/private static boolean executeLinuxCmd(String cmd) throws IOException {Process process = Runtime.getRuntime().exec(cmd);try {process.waitFor();} catch (InterruptedException e) {log.error("executeLinuxCmd 执行Linux命令异常:", e);Thread.currentThread().interrupt();return false;}return true;}/*** 创建临时文件*/private static File createTempFileFromInputStream(InputStream inputStream) {try {File tempFile = File.createTempFile("temp_word", ".docx");Files.copy(inputStream, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);return tempFile;} catch (IOException e) {log.error("创建临时文件失败:", e);throw new RuntimeException("创建临时文件失败", e);}}/*** 读取pdf文件*/private static void readPdfFileToByteArrayOutputStream(File tempFile, OutputStream sourceOutput) {try {Path outputFile = Paths.get(tempFile.getParent(), tempFile.getName().replace(".docx", ".pdf"));Files.copy(outputFile, sourceOutput);} catch (Exception e) {throw new RuntimeException(e);}}
}

同时我也把相关代码上传到了gitee上地址如下:

word转PDF示例: documents4j组件将word文档转成pdf

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • django中的MESSAGE组件
  • 支持S/MIME证书的邮件客户端有哪些?
  • 【Java学习】Stream流详解
  • 短视频SDK解决方案,降低行业开发门槛
  • pytorch实现单层线性回归模型
  • 探索工业互联网智能赋能智能制造算法综述
  • 工程数学线性代数(同济大学数学系)第六版(更新中)
  • 2024 年的 Node.js 生态系统
  • 输出倒闭输入
  • Android Studio报错 Failed to transform ‘...‘ using Jetifier. Reason null
  • 学生阅读行为与图书预定平台的设计与实现(全网独一无二,24年最新定做)
  • Qt 字符串类应用
  • 代码随想录算法训练营第二天 | 滑动窗口 + 螺旋矩阵
  • React概念理解
  • 使用yolov5实现目标检测简单案例(测试图片)
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • ES学习笔记(12)--Symbol
  • JSONP原理
  • php的插入排序,通过双层for循环
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • uni-app项目数字滚动
  • - 概述 - 《设计模式(极简c++版)》
  • ------- 计算机网络基础
  • 记一次用 NodeJs 实现模拟登录的思路
  • 排序算法学习笔记
  • 前端面试之CSS3新特性
  • 区块链分支循环
  • 使用common-codec进行md5加密
  • 我的业余项目总结
  • 移动端唤起键盘时取消position:fixed定位
  • 再次简单明了总结flex布局,一看就懂...
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • # include “ “ 和 # include < >两者的区别
  • #数据结构 笔记三
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (二)丶RabbitMQ的六大核心
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (六)激光线扫描-三维重建
  • (三)elasticsearch 源码之启动流程分析
  • (十一)c52学习之旅-动态数码管
  • (已解决)什么是vue导航守卫
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • (自适应手机端)行业协会机构网站模板
  • ****三次握手和四次挥手
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
  • .Net7 环境安装配置
  • .NET未来路在何方?
  • .Net中wcf服务生成及调用
  • .net专家(高海东的专栏)
  • [2019.3.20]BZOJ4573 [Zjoi2016]大森林
  • [20190113]四校联考