word转pdf技术方案汇总(附代码)

Libreoffice

免费,命令方式执行,20页word耗时2-3s,老版本效果较好(版本5.3.6.1 30),新版本格式有问题(版本24.2)。格式复杂会显示错位。

  • 添加依赖
        <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>
  • 工具类
package com.example.pdfdemo.util;

import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;

@Slf4j
public class LibreofficeUtil {
    
    public static boolean wordConverterToPdf(String docxPath) throws IOException {
        File file = new File(docxPath);
        String path = file.getParent();
        BufferedReader buf = null;
        try {
            String osName = System.getProperty("os.name");
            String command = "";
            if (osName.contains("Windows")) {
                command = "soffice --convert-to pdf  --outdir " + path + " " + docxPath;
            } else {
                command = "libreoffice --invisible --convert-to pdf --outdir " + path + " " + docxPath;
            }
            executeLinuxCmd(command );
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (buf != null) {
                buf.close();
            }
        }
    }
    private static boolean executeLinuxCmd(String cmd)  {
        try {
            Process process = Runtime.getRuntime().exec(cmd);
            process.waitFor();
        } catch (InterruptedException e) {
            log.error("executeLinuxCmd 执行Linux命令异常:", e);
            Thread.currentThread().interrupt();
            return false;
        } catch (IOException e) {
            log.error("获取系统命令执行环境异常", e);
        }
        return true;
    }
}

JODConverter

免费,依赖Openoffice/Libreoffice,比直接使用命令方式慢

  • 添加依赖
        <dependency>
           <groupId>org.jodconverter</groupId>
           <artifactId>jodconverter-local</artifactId>
           <version>4.4.2</version>
       </dependency>
  • 工具类
package com.example.pdfdemo.util;

import org.jodconverter.core.DocumentConverter;
import org.jodconverter.core.document.DefaultDocumentFormatRegistry;
import org.jodconverter.core.office.OfficeUtils;
import org.jodconverter.local.LocalConverter;
import org.jodconverter.local.office.LocalOfficeManager;

import java.io.File;

public class JodconverterUtil {

   public static void wordConverterToPdf(String wordPath, String pdfPath) {
       LocalOfficeManager localOfficeManager = LocalOfficeManager.builder().officeHome("/usr/lib64/libreoffice").install().build();

       try {
           if (!localOfficeManager.isRunning()) {
               localOfficeManager.start();
           }
           DocumentConverter converter = LocalConverter.builder().officeManager(localOfficeManager).build();

           converter.convert(new File(wordPath)).as(DefaultDocumentFormatRegistry.DOCX).to(new File(pdfPath)).as(DefaultDocumentFormatRegistry.PDF).execute();

       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           OfficeUtils.stopQuietly(localOfficeManager);
       }
   }
}

Openoffice

免费,安装及使用上不如libreoffice。

Documents4j‌

免费,依赖Microsoft Office,linux不适用,windows效果好。

  • 添加依赖
        <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>
  • 工具类
package com.example.pdfdemo.util;

import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import lombok.extern.slf4j.Slf4j;

import java.io.*;

@Slf4j
public class Doc4jUtil {
   /**
    * 通过documents4j 实现word转pdf
    *
    * @param wordPath 源文件地址 如 /root/example.doc
    * @param pdfPath 目标文件地址 如 /root/example.pdf
    */
   public static void wordConverterToPdf(String wordPath, String pdfPath) {
       File inputWord = new File(wordPath);
       File outputFile = new File(pdfPath);
       InputStream docxInputStream = null;
       OutputStream outputStream = null;
       try {
           docxInputStream = new FileInputStream(inputWord);
           outputStream = new FileOutputStream(outputFile);
           IConverter converter = LocalConverter.builder().build();
           boolean execute = converter.convert(docxInputStream)
                   .as(DocumentType.DOCX)
                   .to(outputStream)
                   .as(DocumentType.PDF).execute();
           converter.shutDown();
           outputStream.close();
           docxInputStream.close();

           log.info("转换完毕 targetPath = {}", outputFile.getAbsolutePath());
           System.out.println("转换完毕 targetPath = " + outputFile.getAbsolutePath());
           converter.shutDown();
       } catch (Exception e) {
           log.error("word转pdf失败:{}", e.toString());
           throw new RuntimeException(e);
       } finally {
           if (outputStream != null) {
               try {
                   outputStream.close();
               } catch (Exception e) {
                   log.error("关闭outputStream失败:{}", e.toString());
               }
           }
           if (docxInputStream != null) {
               try {
                   docxInputStream.close();
               } catch (Exception e) {
                   log.error("关闭docxInputStream失败:{}", e.toString());
               }
           }
       }
   }
}

Docx4j

免费,会出现乱码或格式错乱的问题。

  • 添加依赖
        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j-core</artifactId>
            <version>8.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j-JAXB-Internal</artifactId>
            <version>8.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j-JAXB-ReferenceImpl</artifactId>
            <version>8.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j-export-fo</artifactId>
            <version>8.3.1</version>
        </dependency>
  • 工具类
package com.example.pdfdemo.util;

import lombok.extern.slf4j.Slf4j;
import org.docx4j.Docx4J;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFont;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.org.apache.poi.util.IOUtils;

import java.io.*;

@Slf4j
public class Docx4jUtil {
   /**
    * docx文档转换为PDF
    *
    * @param pdfPath PDF文档存储路径
    * @throws Exception 可能为Docx4JException, FileNotFoundException, IOException等
    */
   public static void wordConverterToPdf(String docxPath, String pdfPath) {

       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();
       //加载字体文件(解决linux环境下无中文字体问题)
       if (PhysicalFonts.get("SimSun") == null) {
           System.out.println("加载本地SimSun字体库");
//          PhysicalFonts.addPhysicalFonts("SimSun", WordUtils.class.getResource("/fonts/SIMSUN.TTC"));
       }
       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("FangSong"));
       fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));
       fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));
       fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));
       fontMapper.put("等线", PhysicalFonts.get("SimSun"));
       fontMapper.put("等线 Light", PhysicalFonts.get("SimSun"));
       fontMapper.put("华文琥珀", PhysicalFonts.get("STHupo"));
       fontMapper.put("华文隶书", PhysicalFonts.get("STLiti"));
       fontMapper.put("华文新魏", PhysicalFonts.get("STXinwei"));
       fontMapper.put("华文彩云", PhysicalFonts.get("STCaiyun"));
       fontMapper.put("方正姚体", PhysicalFonts.get("FZYaoti"));
       fontMapper.put("方正舒体", PhysicalFonts.get("FZShuTi"));
       fontMapper.put("华文细黑", PhysicalFonts.get("STXihei"));
       fontMapper.put("宋体扩展", PhysicalFonts.get("simsun-extB"));
       fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));
       fontMapper.put("新細明體", PhysicalFonts.get("SimSun"));
       fontMapper.put("REAIGR+SourceHanSansCN-Normal", PhysicalFonts.get("SimSun"));
       //解决宋体(正文)和宋体(标题)的乱码问题
       PhysicalFonts.put("PMingLiU", PhysicalFonts.get("SimSun"));
       PhysicalFonts.put("新細明體", PhysicalFonts.get("SimSun"));
       //宋体&新宋体
       PhysicalFont simsunFont = PhysicalFonts.get("SimSun");
       fontMapper.put("SimSun", simsunFont);
       //设置字体
       mlPackage.setFontMapper(fontMapper);
   }

Apache POI

免费,使用fr.opensagres.xdocreport,格式丢失

  • 添加依赖
        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>org.apache.poi.xwpf.converter.pdf</artifactId>
            <version>1.0.6</version>
        </dependency>
        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>org.apache.poi.xwpf.converter.xhtml</artifactId>
            <version>1.0.6</version>
        </dependency>
  • 工具类
package com.example.pdfdemo.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;

import org.apache.poi.xwpf.converter.pdf.PdfConverter;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

public class XdocReportUtil {

   public static void wordConverterToPdf(String docxPath, String pdfPath) {
       try {
           XWPFDocument document = new XWPFDocument(new FileInputStream(new File(docxPath)));
           PdfOptions options = PdfOptions.create();

           OutputStream out = new FileOutputStream(new File(pdfPath));
           PdfConverter.getInstance().convert(document, out, options);
           out.close();
       } catch(Exception e) {
           e.printStackTrace();
       }
   }
}

‌Apache PDFBox

免费,需自己将格式写入pdf,实现复杂,保留格式较困难。

IText‌

免费,需自己将格式写入pdf,实现复杂,保留格式较困难。

Aspose.Words

付费,效果好,跨平台

Spire.Doc

付费,格式有偏差,免费版仅可转3页

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值