docx文件转pdf,使用aspose words 转pdf,并且解决表格格式错乱

docx文件转pdf,使用aspose words 转pdf,并且解决表格格式错乱

最近遇到一个问题,需要将数据动态生成pdf文件。于是我毫不犹豫的使用poi,计划先将数据写入docx文件,然后再实现docx文件转pdf。就这样,当天我的docx文件已经生成,并且把各种格式,字体,颜色,表格,表格边距等等属性调整完毕,下一步就是转换pdf了(注:不是摸板信息回填,而是根据程序中表单的格式,内容,审批流程等等信息自动生成docx文件,然后提供线下备份及打印功能等等。。。。。。)。然而,理想是丰满的,现实是骨感的。使用poi系列工具类转pdf后,格式一下子就爆炸了,百度了一圈最终放弃,只能另选出路了。
之后,陆续选择了几种转换工具,比如:documents4j,expire,aspose,itextpdf。都尝试过,略微说下使用感受。
1,documents4j
依赖于windows系统和office。使用过程中经常出现 FileInputStream 流信息中断异常,这可能是因为我再使用poi生成的doc文件中存在无法解析的字符,导致officeWord无法正常打开文件,解决这个问题让我头发,果断放弃。然而这也不是主要原因,如果使用该工具,那么我后续就得考虑服务器的问题了,windows系统和office呵呵。。。
2,expire
看了官网介绍,免费的版本只能转换3页,大概记得是这样。总之远远不能满足我的需要,直接忽视。
3,itextpdf
转换之后的pdf格式混乱,字体混乱。使用了一次就果断放弃,没有深入探索。
4,aspose
最终选择aspose,主要是使用方便,能满足我的需要,目前功能已上线,在服务器上运行正常,转换之后格式无偏差,字体显示饱满,特别是表格和图片的处理,就是我需要的。

大概介绍了我选择aspose的原因,大多是个人使用感受。当然,会有其他实现pdf转换的方法或者工具,也有大神可以使用itextpdf实现无偏差转换,或者是有其他看法的。我只是自抒己见而已,勿嘲 勿喷。
接下来介绍aspose 的简单使用

一,依赖下载

阿里云仓库无镜像文件,需要手动下载jar包,然后本地mvn引入依赖
该依赖仅限于学习使用。。。。。
其他版本,可至官网下载。
1,下载jar包
下载地址,提取码:buaz
2,pom中引入依赖

<dependency>
            <groupId>com.aspose.words</groupId>
            <artifactId>aspose-words</artifactId>
            <version>19.5</version>
</dependency>

3,mnv导入本地jar包

mvn install:install-file -DgroupId=com.aspose.words -DartifactId=aspose-words -Dversion=19.5 -Dpackaging=jar -Dfile=写入文件所在地址

二,工具类的使用

1,取消水印处理

将如下代码,写入xml文件中,并且存在到resource路径下,具体位置随意,之后引入即可。

<?xml version="1.0" encoding="UTF-8"?>

<License>
    <Data>
        <Products>
            <Product>Aspose.Total for Java</Product>
            <Product>Aspose.Words for Java</Product>
        </Products>
        <EditionType>Enterprise</EditionType>
        <SubscriptionExpiry>20991231</SubscriptionExpiry>
        <LicenseExpiry>20991231</LicenseExpiry>
        <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
    </Data>
    <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
</License>

图片:
图片上传失败,懒得弄,自己脑补吧。

写一个方法读取xml信息

public static boolean getLicense() {
        boolean result = false;
        InputStream is = null;
        try {
            Resource resource = new ClassPathResource("static/license.xml");
            is = resource.getInputStream();
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

2,实现方法

1,调用去水印方法

getLicense()

2,使用document读取docx文件

Document doc = new Document(new FileOutputStream(new File("文件路径")));

3,写出pdf文件

document.save(new FileOutputStream(new File("输出的pdf地址"), SaveFormat.PDF)

大体上就这么简单。。。。。。。。。。。。。

三,解决表格格式错乱

表格格式混乱,我遇到的就三种
1,在docx文件中表格宽度是100%,自动适应页面宽度。然而转换成pdf后宽度变了,不能铺满页面,也许还更窄,懒得去截图了,这里就不上图了,遇到类似问题的朋友,估计你能很快脑补出来,总之就是你的表格缩水了。
解决方法:在docx文件中设置表格的宽度为固定值,这里我是在poi中设置的,如下:

XWPFTable table = doc.createTable(rows, cols);
table.setWidthType(TableWidthType.DXA);

当然,你也可以手动打开文件,然后进行设置。

2,表格的单元格内容过长后会把整个单元格撑爆,然后连锁反应,使得整个表格超出了页面。
解决方法:这里我之前勿以为是单元格的宽度没有固定死导致的,其实是单元格内容自动换行的问题,查找了poi文档,未能找到自动换行属性的设置,因为poi默认就是自动换行的。

在我把所有目光放在使用使用poi调整格式中,我截然忘记了 Document 这个aspose提供给我们的对象,这个对象也是用来操作文档的,呵呵 活该是个死搬代码。。。。。。。。。

<————————————–

这里需要解释一下为什么转pdf后格式会混乱,我个人认为在document对象读取文件后,某些自定义的属性是没有被写在ooxml文件中的,就比如这个单元格内自动换行。这里我百度后有人说在读取文件后,进行一次复制,并且设置全格式复制模式可以解决,我试过,没成功。

Document doc = new Document(inPath); // 使用document打开一个文件对象
 Document document = new Document();//新创建一个对象
document.removeAllChildren(); 
 document.appendDocument(doc, ImportFormatMode.USE_DESTINATION_STYLES);//保留样式复制

注意,上面这个方法我使用过,没卵用。。。。。。。。。
往下看

———————–>

我们要相信科学,既然没有设置这个属性,那么没有就是没有,别死撑着,使用document设置一下就有了。

File file = new File(outPath); // 新建一个空白pdf文档
            os = new FileOutputStream(file);
            Document document = new Document(inPath); // Address是将要被转化的word文档
            TableCollection tables = document.getFirstSection().getBody().getTables();
            for (Table table : tables) {
                RowCollection rows = table.getRows();
                table.setAllowAutoFit(false);
                for (Row row : rows) {
                    CellCollection cells = row.getCells();
                    for (Cell cell : cells) {
                        CellFormat cellFormat = cell.getCellFormat();
                        cellFormat.setFitText(false);  //设置自适应关闭
                        cellFormat.setWrapText(true);  // 设置自动换行
                    }
                }
            }
            document.save(os, SaveFormat.PDF);

同理,如果你在使用aspose words进行pdf转换的过程中,遇到的格式错乱。千万别犹豫,使用document对象,盘他。

我呢是由于前期使用了poi导出docx文件,其中涉及的样式及数据整理有些复杂,不愿意切换成document,如果你目前有条件的话,我建议试试使用aspose提供的 document对象直接进行操作,应该不会让你失望。

最后,提供下我的util文件

package com.xxx.xx.xxx.common.utils;

import com.aspose.words.*;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class WordToPdfUtil {
    public static boolean getLicense() {
        boolean result = false;
        InputStream is = null;
        try {
            Resource resource = new ClassPathResource("static/license.xml"); // xml文件地址
            is = resource.getInputStream();
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    public static boolean docxToPdf(String inPath, String outPath) {
        if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
            return false;
        }
        FileOutputStream os = null;
        try {
            long old = System.currentTimeMillis();
            File file = new File(outPath); // 新建一个空白pdf文档
            os = new FileOutputStream(file);
            Document document= new Document(inPath); // Address是将要被转化的word文档
            TableCollection tables = document.getFirstSection().getBody().getTables();
            for (Table table : tables) {
                RowCollection rows = table.getRows();
                table.setAllowAutoFit(false);
                for (Row row : rows) {
                    CellCollection cells = row.getCells();
                    for (Cell cell : cells) {
                        CellFormat cellFormat = cell.getCellFormat();
                        cellFormat.setFitText(false);
                        cellFormat.setWrapText(true);
                    }
                }
            }
            document.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
// EPUB, XPS, SWF 相互转换
            long now = System.currentTimeMillis();
            System.out.println("pdf转换成功,共耗时:" + ((now - old) / 1000.0) + "秒"); // 转化用时
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }finally {
            if (os != null) {
                try {
                    os.flush();
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }
}

    原文作者:Mr_going
    原文地址: https://blog.csdn.net/Mr_going/article/details/120097390
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞