实现Word转Pdf文件

在项目中需要以Word文件为模板,填充指定数据,并转换为Pdf文件。可以分为两步,第一步使用POI进行文本替换,第二步把替换后的Word转换为pdf文件。

当前遇到的问题是网上所有的转换工具依赖的包都过大,一般要30M以上。而自己通过Poi实现转换的成本又太高,且转换效果不够理想。最终尝试一下,先从Word转换为HTML,然后再从HTML转换为pdf。

虽然转换成功了,但是由于在从word转换给html时使用了ooxml-schema.jar包,此包有十几兆,总依赖仍旧超过30M。最终放弃了此方法。当过程值得记录下来,以供以后参考。

1.Word转换为html

除了poi相关包(我当前使用的4.1.2版本)以外,还需要ooxml-schemas.jar和xdocreport.jar,依赖配置如下:

            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>ooxml-schemas</artifactId>
                <version>1.4</version>
            </dependency>
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>xdocreport</artifactId>
                <version>2.0.2</version>
            </dependency>

代码实现及注释如下:

 /**
     * docx文件转html
     * 参考: https://wooaooo.com/2022/02/12/Java/POI/java-poi5.2.0-word-to-html/
     * @param wordInput word文件输入流。
     * @param  data 需要填充的数据。
     */
    public static String word2007ToHtml(InputStream wordInput, Map<String, String> data)
            throws IOException {

        // 加载word文档生成 XWPFDocument对象
        XWPFDocument document = new XWPFDocument(wordInput);

        //  带图片的word,则将图片转为base64编码,保存在一个页面中
        XHTMLOptions options = XHTMLOptions.create().indent(3).setImageManager(new Base64EmbedImgManager());
        //若设置true,表示外层没有html\head\body标签,设为false,保留html等标签。
        options.setFragment(true);
        //转换为html
        StringWriter writer = new StringWriter();
        XHTMLConverter xhtmlConverter = (XHTMLConverter) XHTMLConverter.getInstance();
        xhtmlConverter.convert(document, writer, options);
        String html = writer.toString();
        // 解析html并优化布局
        Document doc = Jsoup.parseBodyFragment(html);
        //去掉页边距和固定宽度
        Elements elements = doc.getElementsByTag("div");
        for(Element element : elements){
            element.attr("style","line-height:2em;margin-left: 3em; margin-right: 3em;");
        }
        //设置所有table的样式
        Elements tables = doc.getElementsByTag("table");
        for (Element table : tables) {
            table.attr("style", "border-collapse: collapse;");
        }
        //文本替换。
        html = doc.outerHtml();
        for(Map.Entry<String,String> item : data.entrySet()){
            html = html.replace(item.getKey(),item.getValue());
        }
        return html;
    }

2.html转换为pdf

需要用到的jar包配置如下:

            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itext7-core</artifactId>
                <version>${itextpdf.version}</version>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>font-asian</artifactId>
                <version>${itextpdf.version}</version>
            </dependency>
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>html2pdf</artifactId>
                <version>3.0.3</version>
            </dependency>

代码实现及注释如下:

    /**
     * html转换为pdf
     * @param html html文本内容
     * @param output pdf文件输出
     */
    public static void htmlToPdf(String html, OutputStream output) throws IOException {
        //转换时参数配置,例如字体,依赖图片等文件路径
        ConverterProperties properties = new ConverterProperties();
        //必须设置字体,否则转换的pdf文件不显示汉字
        FontProvider fp = new FontProvider();
        fp.addFont(FontProgramFactory.createFont("STSong-Light"),"UniGB-UCS2-H");
        properties.setFontProvider(fp);
        //转换
        try(PdfDocument pdfDocument = new PdfDocument(new PdfWriter(output))){
            //设置pdf页面大小为A4
            pdfDocument.setDefaultPageSize(PageSize.A4);
            HtmlConverter.convertToPdf(html,pdfDocument,properties);
        }
    }

3.其他实现word转换pdf的方法

其他实现word转换为pdf的方法可以参考:Java开发中Word转PDF文件5种方案横向评测,我最终选择的是aspose-words,因为其转换效果比较好,依赖包相对比较小,且代码量少。

放弃了通过html转换pdf后,就可以直接通过Word转换为pdf了。需要通过poi-tl.jar来实现word中的数据替换,然后再通过aspose-words.jar转换为pdf。依赖包如下:

    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>4.1.2</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>4.1.2</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml-schemas</artifactId>
      <version>4.1.2</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.deepoove</groupId>
      <artifactId>poi-tl</artifactId>
      <version>1.10.5</version>
    </dependency>
    <dependency>
      <groupId>com.luhuiguo</groupId>
      <artifactId>aspose-words</artifactId>
      <version>23.1</version>
    </dependency>

代码实现相当简单,如下:

package com.zhengzhaoxi.web.common;

import com.aspose.words.Document;
import com.aspose.words.PdfSaveOptions;
import com.deepoove.poi.XWPFTemplate;

import java.io.*;
import java.util.Map;

/**
 * Word工具类
 * @author donghx
 * @author 2023-06-14
 */
public class WordUtils {

    /**
     * 填充数据
     * @param input 输入word文件数据流
     * @param data 需要替换的数据映射
     * @param output 输出的word文件数据量
     * @throws IOException
     */
    public static void fillData(InputStream input, Map<String, Object> data, OutputStream output) throws IOException {
        //使用poi-tl.jar中的类填充数据
        try(XWPFTemplate template = XWPFTemplate.compile(input) ){
            template.render(data).writeAndClose(output);
        }catch (Exception ex){
            throw ex;
        }
    }

    /**
     * word转换为pdf
     * @param wordInput word文件输入流
     * @param pdfOutput pdf文件输出流
     * @throws Exception
     */
    public static void wordToPdf(InputStream wordInput, OutputStream pdfOutput) throws Exception {
        //通过aspose-words.jar中的类转换文件
        Document wordDoc = new Document(wordInput);
        if(SystemUtils.isLinux()){
            //设置汉字字体,否则转换后的文档汉字会乱码。
            FontSettings settings = new FontSettings();
            settings.setFontsFolder("/mydata/fonts",false);
            wordDoc.setFontSettings(settings);
        }
        PdfSaveOptions pso = new PdfSaveOptions();
        wordDoc.save(pdfOutput, pso);
    }
}

在word转换为pdf方法中,必须设置中文字体所在的目录。有两种方法:

  1. 把字体防止在目录/usr/share/fonts/下面,需要使用命令fontconfig 和mkfontscale 配置系统字体。
  2. 直接把字体复制到指定目录下,并在代码中指定此目录即可,如上面的示例。字体文件可以从Windows操作系统中复制过去。Windows字体目录为:C:\Windows\Fonts
  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Aspose是一种强大的文件处理库,可以用于实现Word文件换为PDF文件的功能。使用Aspose可以高效地将Word文件换为PDF文件,并且在换过程中不会丢失文档的质量。 要使用Aspose实现WordPDF文件的功能,首先需要安装相应的Aspose库文件。然后,可以通过编程的方式使用Aspose库来读取Word文件并将其换为PDF格式。 Aspose提供了丰富的API和方法,可以灵活地控制换过程中的各种参数和选项。用户可以根据需要设置字体、布局、页眉页脚、文本样式、图片处理等功能,以确保换后的PDF文件符合预期。 使用Aspose进行WordPDF的好处是,它能够高效地处理大型的Word文件,并保持文档内容的准确性和完整性。无论是处理数百页的复杂文档,还是换包含大量图像和表格的文件,Aspose都能够快速且准确地生成高质量的PDF文件。 此外,Aspose还支持将Word文件中的书签、超链接、目录等元数据保留在换后的PDF文件中。这意味着用户可以轻松地在PDF文件中进行导航和查找。 总之,Aspose是一种可靠且功能强大的工具,可以高效地将Word文件换为PDF文件。无论是为了保持文件格式的一致性,还是为了便于文件的共享和分发,Aspose都是一个值得考虑的选择。 ### 回答2: Aspose是一种强大的文件处理库,可以实现Word文档换为PDF格式的功能,而且换过程高效且不会损失文件的质量。 首先,使用Aspose提供的API,我们可以轻松地将Word文档加载到内存中,并进行各种操作,比如修改内容、格式化文本、插入表格、添加图片等。无论文档有多复杂,Aspose都能够正确地识别和处理。 接下来,我们可以使用Aspose提供的方法,将已经处理好的Word文档换为PDF格式。在换的过程中,Aspose会自动处理文档的布局、样式、图像和字体等方面,确保最终的PDF文件与原始的Word文档保持一致,不会出现任何失真。 AsposeWordPDF的过程也非常高效。它利用了优化的算法和多线程处理技术,可以快速地处理大型的Word文档。无论文档的复杂度和大小如何,Aspose都能够保持高效的性能,给用户提供快速而稳定的换体验。 总的来说,Aspose是一个功能强大且高效的工具,可以帮助用户轻松地实现Word文档到PDF文件换。无论是对于个人用户还是企业用户来说,Aspose都是一个值得信赖的解决方案,可以满足各种换需求。同时,Aspose的换过程也非常稳定,不会引起任何质量上的损失。 ### 回答3: Aspose是一种功能强大的文件处理库,它可以实现Word文件换为PDF文件,并且在换过程中能够保持高效和不失真的特点。 首先,Aspose提供了丰富的API和功能,可以轻松地将Word文件加载到代码中进行处理。无论是doc还是docx格式的Word文件,Aspose都可以处理。 其次,Aspose具有高效的处理能力,可以在短时间内将大量的Word文件批量换为PDF文件。无论是单个文件还是多个文件,Aspose都能够快速而准确地完成换任务。 此外,Aspose的换过程非常稳定,不会出现数据丢失或换错误的情况。它能够准确地将Word文件中的文本、表格、图片等元素换为PDF文件,并且保持原始文件的格式和布局。 另外,Aspose提供了丰富的设置选项,可以根据需要进行自定义设置。例如,可以设置PDF的页面大小、页面方向、页眉页脚、字体样式等。这些设置选项可以确保最终生成的PDF文件符合用户的需求和要求。 总结来说,Aspose是一种高效且不失真的工具,能够帮助我们实现Word文件PDF文件换。无论是在速度、准确性还是功能方面,Aspose都是一个理想的选择。通过使用Aspose,我们可以轻松地将Word文件换为PDF文件,并且确保换过程中不会出现任何质量损失。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WalsonTung

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值