Java 使用 aspose-cells 转 Excel 为 PDF 丢失表格线,列过多分页,单元格内容显示不全问题

目录

问题

前置环境

apose-cells-8.5.2.jar

license.xml

pom

excel

问题复现

如何解决

最终代码


问题

工作中遇到一个需求,需要实现 excel 文件的预览,实现的思路就是将 excel 转成 pdf 文件,上传到文件服务器上得到文件地址,预览时只需要返回 pdf 预览文件地址即可。

所以主要的问题就是如何将 excel 转为 pdf,调研了相关的技术,最简单的就是使用 aspose 类库,直接一个api调用就搞定了。但是直接这么使用会出现转换后的 pdf 文件单元格没有表格线,表格列过多会自动分页,单元格内容过多时,在 pdf 的单元格里内容显示不全情况。

前置环境

由于 aspose 产品并不是免费的,如果直接使用,转换后的 pdf 会带有水印。

网上能找到破解版的 license,对应的 jar 包是 apose-cells-8.5.2.jar,这个版本已经在 maven 中已经下载不到了,所以需要从网上找到资源下载。

apose-cells-8.5.2.jar

链接:嘿嘿嘿

提取码:eqy8

下载 apose-cells-8.5.2.jar,这里是放到了 resource/lib 下

license.xml

内容如下

XML 复制代码
<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>

pom

XML 复制代码
        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>aspose-cells</artifactId>
            <version>8.5.2</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/lib/aspose-cells-8.5.2.jar</systemPath>
        </dependency>

excel

准备一个 excel 文件,列多一些,并且每个单元格内容长度都大于显示的长度

问题复现

使用 aspose 转 excel 为 pdf 非常方便,只需要调个 api 就行了

Excel2PDFUtil

java 复制代码
public class Excel2PDFUtil {


    public static boolean getLicense() {
        boolean result = false;
        try {
            InputStream is = Excel2PDFUtil .class.getClassLoader().getResourceAsStream("\\license.xml");
            License asposeLic = new License();
            asposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     * excel 转 pdf
     *
     * @param excelPath excel文件路径
     * @param pdfPath pdf文件路径
     */

    public static Boolean excel2pdf(String excelPath, String pdfPath) {
        if (!getLicense()) {
            return false;
        }

        try {
            Workbook wb = new Workbook(excelPath);

            File pdfFile = new File(pdfPath);
            FileOutputStream fileOS = new FileOutputStream(pdfFile);

            wb.save(fileOS, SaveFormat.PDF);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

测试代码

java 复制代码
class Excel2PDFUtilTest {

    @Test
    void excel2pdf() {
        String excelPath = "C:\\Users\\luhc\\Desktop\\excel.xlsx";
        String pdfPath = "C:\\Users\\luhc\\Desktop\\pdf.pdf";

        Excel2PDFUtil.excel2pdf(excelPath, pdfPath);
    }
}

生成的 PDF 如下所示

可以看到转换后的 PDF 单个表格被分成了 2 页面来显示,而且每行单元格没有边框,并且每个单元格显示的内容也不全,这样转换得到的 pdf 是没有任何用处的,毫无意义。

如何解决

单元格的边框和单元格内容显示不全的问题,是可以在 excel 中设置单元格边框和文本自动换行来解决,这样直接转换的 pdf 就没问题了,这些设置实际上也可以由代码来设置,就不用去考虑 excel 源文件的单元格格式是否符合要求了。

至于列过多导致的分页问题,则可以在转换 pdf 时设置缩放参数

java 复制代码
PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
pdfSaveOptions.setOnePagePerSheet(true);

最终代码

java 复制代码
public class Excel2PDFUtil {

    public static boolean getLicense() {
        boolean result = false;
        try {
            InputStream is = Excel2PDFUtil.class.getClassLoader().getResourceAsStream("\\license.xml");
            License asposeLic = new License();
            asposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     * excel 转 pdf
     *
     * @param excelPath excel文件路径
     * @param pdfPath pdf文件路径
     */

    public static Boolean excel2pdf(String excelPath, String pdfPath) {
        if (!getLicense()) {
            return false;
        }

        try {
            Workbook wb = new Workbook(excelPath);
            WorksheetCollection sheets = wb.getWorksheets();
            int sheetCount = sheets.getCount();
            for (int i = 0; i < sheetCount; i++) {
                Worksheet sheet = sheets.get(i);

                sheet.autoFitRows();

                Cells cells = sheet.getCells();
                int maxRow = cells.getMaxRow();
                int maxColumn = cells.getMaxColumn();
                for (int j = 0; j < maxRow; j++) {
                    for (int k = 0; k < maxColumn; k++) {
                        Cell cell = cells.get(j, k);
                        Style style = cell.getStyle();
                        BorderCollection borders = style.getBorders();
                        borders.getByBorderType(BorderType.TOP_BORDER).setLineStyle(CellBorderType.THIN);
                        borders.getByBorderType(BorderType.TOP_BORDER).setColor(Color.getBlack());
                        borders.getByBorderType(BorderType.BOTTOM_BORDER).setLineStyle(CellBorderType.THIN);
                        borders.getByBorderType(BorderType.BOTTOM_BORDER).setColor(Color.getBlack());
                        borders.getByBorderType(BorderType.LEFT_BORDER).setLineStyle(CellBorderType.THIN);
                        borders.getByBorderType(BorderType.LEFT_BORDER).setColor(Color.getBlack());
                        borders.getByBorderType(BorderType.RIGHT_BORDER).setLineStyle(CellBorderType.THIN);
                        borders.getByBorderType(BorderType.RIGHT_BORDER).setColor(Color.getBlack());

                        style.setHorizontalAlignment(TextAlignmentType.CENTER);

                        cell.setStyle(style);
                    }
                }
            }

            File pdfFile = new File(pdfPath);
            FileOutputStream fileOS = new FileOutputStream(pdfFile);

            PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
            pdfSaveOptions.setOnePagePerSheet(true);
            
            wb.save(fileOS, pdfSaveOptions);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}
相关推荐
星间都市山脉5 小时前
Android16 SystemService.onBootPhase 调用时机
android·java·linux·windows·ubuntu
深入云栈5 小时前
Netty 4.2.x 源码深度解析 (十三):Epoll 传输 —— Linux 高性能 IO 的 Netty 实现
java·后端
ynchyong5 小时前
Linux nohup 后台服务合并标准错误输出到一个文件
java·linux·运维
用户3126874877205 小时前
Lombok 的 @Data 到底怎么工作的?Java 注解处理器实战全链路拆解
java
小羊没烦恼!5 小时前
Memory 记忆设计讨论:为什么 Agent Memory 不能只靠向量数据库?
java·开发语言·windows·算法·c#
天远API5 小时前
零信任架构实战:基于天远单人婚姻查询构建自动化联合贷款审计网关
java·人工智能·架构·自动化
九皇叔叔5 小时前
从本地事务到分布式事务
java·分布式·分布式事务·cap·base
黑马程序员毕设6 小时前
基于微信小程序的节目活动报名与管理系统设计与实现
java·开发语言·spring boot·后端·电脑
小坏讲微服务6 小时前
Spring AI 高频面试题20道
java·spring·ai·agent·springai
Bs_MoneyMagnet6 小时前
基于springboot+vue的会议室预约管理系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring·毕业设计·计算机毕业设计