利用docx4j word转pdf

news/2024/11/28 2:48:41/

依赖:

<docx4j.version>6.1.1</docx4j.version>
<export.fo.version>8.1.1</export.fo.version><!--word 转 pdf -->
<dependency><groupId>org.docx4j</groupId><artifactId>docx4j</artifactId><version>${docx4j.version}</version>
</dependency>
<dependency><groupId>org.docx4j</groupId><artifactId>docx4j-export-fo</artifactId><version>${export.fo.version}</version>
</dependency>

工具类

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.docx4j.Docx4J;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.org.apache.poi.util.IOUtils;import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
public class WordUtils {public static void main(String[] args) throws Exception {WordUtils.convertDocxToPdf("D:/test.docx","D:/test.pdf");}/*** docx文档转换为PDF* @param body 文档* @param response 响应给前端* @return pdf 输出流* @throws Exception 可能为Docx4JException, FileNotFoundException, IOException等*/public static void convertDocxToPdf(byte[] body , HttpServletResponse response) throws Exception {response.setContentType("application/pdf");File docxFile = FileUtil.byteToFile(body, UUID.randomUUID().toString() + ".docx");try {WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(docxFile);setFontMapper(mlPackage);Docx4J.toPDF(mlPackage, response.getOutputStream());}catch (Exception e){e.printStackTrace();log.error("docx文档转换为PDF失败");}FileUtil.deleteTempFile(docxFile);}/*** docx文档转换为PDF** @param pdfPath PDF文档存储路径* @throws Exception 可能为Docx4JException, FileNotFoundException, IOException等*/public static void convertDocxToPdf(String docxPath, String pdfPath) throws Exception {FileOutputStream fileOutputStream = null;try {File file = new File(docxPath);fileOutputStream = new FileOutputStream(new File(pdfPath));WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(file);setFontMapper(mlPackage);Docx4J.toPDF(mlPackage, new FileOutputStream(new File(pdfPath)));}catch (Exception e){e.printStackTrace();log.error("docx文档转换为PDF失败");}finally {IOUtils.closeQuietly(fileOutputStream);}}private static void setFontMapper(WordprocessingMLPackage mlPackage) throws Exception {Mapper fontMapper = new IdentityPlusMapper();fontMapper.put("隶书", PhysicalFonts.get("LiSu"));fontMapper.put("宋体", PhysicalFonts.get("SimSun"));fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft Yahei"));fontMapper.put("黑体", PhysicalFonts.get("SimHei"));fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));fontMapper.put("宋体扩展", PhysicalFonts.get("simsun-extB"));fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));mlPackage.setFontMapper(fontMapper);}
}

太多的word转pdf搜索出来的资料,版本号不是太旧,就是太繁琐,或者仅支持window,折腾了两天,最后还好找对了资料:https://blog.csdn.net/Jason_996/article/details/81707485

感谢这位博主。虽然版本有点旧,但我整了一下,发现居然只用了两个依赖就能实现了。注:数学部分特殊字符无法正常转换

相关工具类:

import java.util.Arrays;public class CalculateUtil {public static Integer add(Integer... integers){return Arrays.stream(integers).filter(integer -> integer!=null).reduce(0, (a, b) -> a + b);}public static void main(String[] args) {Integer integer = new Integer(1);Integer first = null;Integer add = add(integer, first);System.out.println(add);}}

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;import lombok.extern.slf4j.Slf4j;@Slf4j
public final class FileUtil {public static final String XLSX_SUFFIX = ".xlsx";private FileUtil() {}/*** 文件转比特流*/public static byte[] fileToByte(String filePath) {File file = new File(filePath);return FileUtil.fileToByte(file);}/*** 文件转比特流*/public static byte[] fileToByte(File file) {byte[] buffer = null;try {FileInputStream fis = new FileInputStream(file);ByteArrayOutputStream bos = new ByteArrayOutputStream();byte[] b = new byte[1024];int n;while ((n = fis.read(b)) != -1) {bos.write(b, 0, n);}fis.close();bos.close();buffer = bos.toByteArray();} catch (IOException e) {e.printStackTrace();}return buffer;}/*** 比特流转文件*/public static File byteToFile(byte[] buf, String fileName) {BufferedOutputStream bos = null;FileOutputStream fos = null;File file = null;try {file = new File(fileName);fos = new FileOutputStream(file);bos = new BufferedOutputStream(fos);bos.write(buf);} catch (Exception e) {e.printStackTrace();} finally {if (bos != null) {try {bos.close();} catch (IOException e) {e.printStackTrace();}}if (fos != null) {try {fos.close();} catch (IOException e) {e.printStackTrace();}}}return file;}/*** 删除临时文件*/public static void deleteTempFile(File file) {if (file == null) {return;}boolean delete = file.delete();if (!delete) {log.error("删除临时文件失败");}}/*** 返回带点的后缀* * @param ext* @return*/public static String getExt(String ext) {return ext.indexOf(".") == -1 ? "." + ext : ext;}/*** 返回一个临时文件名不带后缀* * @return*/public static String createTempFileName() {String folder = System.getProperty("java.io.tmpdir");String filename = folder + UUID.randomUUID();return filename;}/*** 截取文件的后缀名 无后缀返回“”* * @param fileName* @return*/public static String cutFileName(String fileName) {String ext = StringUtil.cutName(fileName, ".");return ext == null ? "" : ext;}/*** 生成一个临时文件*/public static File tempFile(String suffix) {String folder = System.getProperty("java.io.tmpdir");String fileName = System.currentTimeMillis() + suffix;String s = folder + fileName;return new File(s);}/*** 生成临时文件和file文件名字一样的*/public static File tempFile(File file) {String folder = System.getProperty("java.io.tmpdir");String s = folder + file.getName();return new File(s);}/*** 创建一个临时目录 + 文件名字符串*/public static String getTempFileName(String fileName) {String folder = System.getProperty("java.io.tmpdir");return folder + "/" + fileName;}/*** 同名文件命名, 例如 1. a.pdf --> a(1).pdf 2. a --> a(1) 3. a(1).pdf --> a(2).pdf* 4. a(1) --> a(2)* * @param fileName* @return*/public static String renameSameFileName(String fileName) {String newFileName = null;int i = fileName.lastIndexOf(".");if (i != -1) { // 有同名文件,有.作为后缀String rule = "(.*)\\.(.*)";Matcher matcher = Pattern.compile(rule).matcher(fileName);if (matcher.find()) {String fileNameNoSuffix = matcher.group(1); // 文件名String suffix = matcher.group(2);String rule2 = "(.*)\\((\\d)\\)";Matcher matcher1 = Pattern.compile(rule2).matcher(fileNameNoSuffix);if (matcher1.find()) {// 同名的文件名是 文件名(1).pdf 这种String number = matcher1.group(2);Integer newNumber = CalculateUtil.add(Integer.valueOf(number), 1);newFileName = fileNameNoSuffix.replaceAll(rule2, "$1").concat("(" + newNumber + ").").concat(suffix);} else { // 同名的文件名是 文件名.pdf这种 直接添加 (1).pdfnewFileName = fileName.replaceAll(rule, "$1(1).$2");}}} else {// 有同名文件,没有以.作为后缀String rule2 = "(.*)\\((\\d)\\)";Matcher matcher1 = Pattern.compile(rule2).matcher(fileName);if (matcher1.find()) {// 同名的文件名是 文件名(1) 这种String number = matcher1.group(2);Integer newNumber = CalculateUtil.add(Integer.valueOf(number), 1);newFileName = fileName.replaceAll(rule2, "$1").concat("(" + newNumber + ")");} else {newFileName = fileName.concat("(1)");}}return newFileName;}/*** 截取 /sdfs/sdfsdf.pdf 中的sdfsdf.pdf* * @param filePath* @return*/public static String getFileNameByPath(String filePath) {String rule = "(.*/)(.*)";String fileName = filePath.replaceAll(rule, "$2");return fileName;}
}

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class StringUtil extends StringUtils {/*** 转换为下划线** @param camelCaseName* @return*/public static String underscoreName(String camelCaseName) {StringBuilder result = new StringBuilder();if (camelCaseName != null && camelCaseName.length() > 0) {result.append(camelCaseName.substring(0, 1).toLowerCase());for (int i = 1; i < camelCaseName.length(); i++) {char ch = camelCaseName.charAt(i);if (Character.isUpperCase(ch)) {result.append("_");result.append(Character.toLowerCase(ch));} else {result.append(ch);}}}return result.toString();}/*** 转换为驼峰** @param underscoreName* @return*/public static String camelCaseName(String underscoreName) {StringBuilder result = new StringBuilder();if (underscoreName != null && underscoreName.length() > 0) {boolean flag = false;for (int i = 0; i < underscoreName.length(); i++) {char ch = underscoreName.charAt(i);if ("_".charAt(0) == ch) {flag = true;} else {if (flag) {result.append(Character.toUpperCase(ch));flag = false;} else {result.append(ch);}}}}return result.toString();}/*** 截取文件后缀*/public static String cutName(String fileName,String cutString){int i = fileName.lastIndexOf(cutString);if (i==-1) {return null;}else{return fileName.substring(i + 1);}}/*** 劈开某个字符串得到list*/public static List<String> splitString(String source,String str){List<String> list = new ArrayList<>();String[] split = source.split(str);Collections.addAll(list,split);return list;}/*** 去除正则的特殊符号 ( )*/public static String removeRegex(String source){return source.replaceAll("\\(|\\)", "");}/*** 去除空白符 再去除 正则特殊符号*/public static String removeBlankAndRegex(String source){return removeRegex(removeBlank(source));}/*** 去除空白符*/public static String removeBlank(String source){return source.replaceAll("\\s", "");}/*** 正则匹配* @param source* @param rule* @return*/public static Matcher match(String source,String rule){Pattern compile = Pattern.compile(rule);Matcher matcher = compile.matcher(source);if (matcher.find()) {return matcher;}return null;}public static String mybitsIds(List<Integer> list, String splits){String join = org.apache.commons.lang3.StringUtils.join(list, splits);return addAfterAndBefore("(", join, ")");}/*** 在string的前后添加字符* @param after* @param source* @param before* @return*/public static String addAfterAndBefore(String after,String source,String before){StringBuilder stringBuilder = new StringBuilder(after);return stringBuilder.append(source).append(before).toString();}/*** 两个字符串中间添加字符串* @param header* @param tail* @param middle* @return*/public static String addMiddle(String header,String tail,String... middle){StringBuilder stringBuilder = new StringBuilder(header);for (String s : middle) {stringBuilder.append(s);}return stringBuilder.append(tail).toString();}/*** 拼接带有参数的url,url后面有?拼接成 &xxx=xxx,没有?拼接?* @param url* @param param* @return*/public static String concatUrl(String url,String... param){StringBuilder stringBuilder = new StringBuilder(url);String join = String.join("&", param);if (url.indexOf("?")!=-1) {return stringBuilder.append("&").append(join).toString();}else {StringBuilder append = stringBuilder.append("?");return append.append(join).toString();}}

 


http://www.ppmy.cn/news/749436.html

相关文章

documents4j 实现Word文档、xlsx、等格式转换PDF文件

1、documents4j 简介 document4j是一个用来进行文档格式转换的Java工具库&#xff0c;它通过借助本机中支持指定文件格式到目标文件格式转换的应用&#xff0c;来实现整个转换的过程。 document4j 实现了Microsoft Word、Excel的适配功能&#xff0c;可以将docx文件转换为pdf文…

Word打印或打印预览或另存为PDF时出现“错误!未定义书签!”的解决办法

出处&#xff1a;http://blog.sina.com.cn/s/blog_5ee0924f0101a05l.html 今天在单独打印一份三页的目录Word文档时&#xff0c;所有目录的页码全部变为“错误&#xff01;未定义书签&#xff01;”&#xff0c;很是奇妙&#xff01;一开始还以为是打印问题&#xff0c;又重新打…

计算机word打不原因什么意思,电脑上Word无法进行打印的原因分析和解决方法

我们在Word上编辑文档&#xff0c;开会时需要打印成纸质的&#xff0c;这时就需要使用到打印机了&#xff0c;但是有用户反映说&#xff0c;在电脑上的Word无法使用打印机进行打印&#xff0c;这是怎么回事&#xff0c;该怎么来解决&#xff1f;造成Word无法使用打印机进行打印…

Windows10 下,pdf可以打印,但记事本打印报错“参数错误”,word打印无响应的原因

Temp目录是否有足够的权限。如果无法生成临时文件&#xff0c;就是这个错误。

pdf2docx安装问题

问题&#xff1a;直接pip install pdf2docx会报错 原因&#xff1a;会捆绑安装PyMuPDF&#xff0c;默认最高版本。python3.6环境不支持 解决&#xff1a; pip install PyMuPDF1.19.1pip install pdf2docx 参考&#xff1a; (17条消息) 用python把pdf文件转换为word文件 | …

ubuntu实现自动挂载u盘

ubuntu实现自动挂载u盘 但是&#xff0c;有些设施可以在没有图形工具的情况下进行复制&#xff0c;并且在系统上占用的空间非常小。 例如&#xff0c;在我的设置中&#xff0c;我已经实现了USB自动挂载服务&#xff0c;而无需使用任何外部工具/服务&#xff0c;只有udev和syst…

机器学习(ML)策略

目录 1、正交化的概念 2、单一数字评估指标&#xff08;Single number evaluation metric&#xff09; 3、训练/开发/测试集划分 4、迁移学习 5、多任务学习 6、端到端深度学习 1、正交化的概念 正交化是机器学习中一种常用的数据预处理技术&#xff0c;用于减少特征之间…

电梯门机机构SW金属板材CNC数控等离子切割机SW雷恩MW54燃气涡轮发动机SW印刷贴标机UG非标转盘式锁螺丝机SW全自动打标机stpFPC裁切检测机屏幕排线裁切断设备FPC软排线裁切机S

电梯门机机构SW金属板材CNC数控等离子切割机SW雷恩MW54燃气涡轮发动机SW印刷贴标机UG非标转盘式锁螺丝机SW全自动打标机stpFPC裁切检测机屏幕排线裁切断设备FPC软排线裁切机SWJM9T武汉埃瑞特的液压台式铆接机旋铆机3D模型三维图纸8宇球244系列HDMI测试包装机三维图轴承输送阻挡…