Java轻松实现Excel转PDF的实战指南

 更新时间:2026年03月23日 08:48:50   作者:Java小王子呀  
这篇文章主要介绍了两种将Excel转换为PDF的方法,第一种使用Spire.XLS免费版,第二种方法(破解版)支持多页转换,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下

一、只适合三页内的PDF

使用几行代码就可以将我们的Excel转为PDF格式,

先说缺点:这个jar包是收费的,只能导出3页,不适合超过3页PDF文件的转换。

1、在pom文件中导入workbook的所需依赖

<dependency>
    <groupId>e-iceblue</groupId>
    <artifactId>spire.xls.free</artifactId>
    <version>5.1.0</version>
</dependency>

如果不能自动导入,则手动导入

下载jar包到本地后

2.Win+R打开运行,输入cmd回车打开doc命令窗口

mvn install:install-file -Dfile=D:\spire.xls.free-5.1.0.jar -DgroupId=e-iceblue -DartifactId=spire.xls.free -Dversion=5.1.0 -Dpackaging=jar

显示如下图就是成功了

3.使用workbook导出整个Excel文件的代码只需要两步,我们可以直接看代码示例:

    /**
     * 使用spire简单整个Excel转换为pdf
     *
     * @param inputFilePath Excel文件路径
     * @param outputFilePath 导出的PDF文件路径
     */
    public static void totalExcelToPDF(String inputFilePath, String outputFilePath) {
        Workbook wb = new Workbook();
//        引入Excel文件
        wb.loadFromFile(inputFilePath);
//        导出PDF文件
        wb.saveToFile(outputFilePath, FileFormat.PDF);
    }

本地文件快速测试:

import com.spire.xls.FileFormat;
import com.spire.xls.Workbook;

    @Test
    public void test() {
        // Excel文件路径
        String excelFilePath = "C:\\Users\\admin\\Downloads\\crossdock_plan_bol_2025-10-22 (1)\\test.xlsx";
        
        // 加载Excel文件
        Workbook workbook = new Workbook();
        workbook.loadFromFile(excelFilePath);
        
        // 构造PDF文件路径(与Excel文件同路径,仅文件扩展名不同)
        String pdfFilePath = excelFilePath.replaceAll("\\.xlsx$", ".pdf");

        // 保存为PDF到同路径下
        workbook.saveToFile(pdfFilePath, FileFormat.PDF);
        
        System.out.println("PDF文件已保存到: " + pdfFilePath);
    }

也指定单个的sheet页转为PDF,输入指定的sheet页的下标即可。代码示例如下:

/**
 * 使用spire将单个sheet转成pdf
 *
 * @param inputFilePath Excel文件路径
 * @param outputFilePath 导出的PDF文件路径
 * @param sheetNum 导出的sheet页下标
 */
public static void partExcelToPDF(String inputFilePath, String outputFilePath, int sheetNum) {
    //加载Excel文档
    Workbook wb = new Workbook();
    wb.loadFromFile(inputFilePath);
    //获取到哪一个sheet页
    Worksheet sheet = wb.getWorksheets().get(sheetNum);
    //调用方法保存为PDF格式
    sheet.saveToPdf(outputFilePath);
}

补充:

这个好像也可以,都差不多

<dependency>
    <groupId>e-iceblue</groupId>
    <artifactId>spire.pdf.free</artifactId>
    <version>9.13.0</version>
</dependency>

二、多页的(破解版)

移除水印原理:

替换指定文字为白色的遮罩层

            String afterDestPdfFileName = "formal-" + middleFileName + ".pdf";
            AsposePdfUtil.replaceStr(attachRecordsThinVo.getDirectoryName().concat(destPdfFileName),
                    attachRecordsThinVo.getDirectoryName().concat(afterDestPdfFileName),
                    "Evaluation Only. Created with Aspose.Cells for Java.Copyright 2003 - 2023 Aspose Pty Ltd.");
    /**
     * 替换指定文字为白色的遮罩层
     * @param src 需要被转换的带全路径文件名
     * @param dest 转换之后pdf的带全路径文件名
     * @param replaceStr 指定转换的文字(水印的文字)
     */
    public static void replaceStr(String src, String dest, String replaceStr) {
        try {
            List<String> resu = new ArrayList<>();
            PdfReader reader = new PdfReader(src);
            //获取指定文字的坐标(就是上一步生成的pdf水印)
            getKeyWords(reader,replaceStr,resu);
            PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
            for (int i = 1; i <= resu.size(); i++) {
                String xy = resu.get(i - 1);
                PdfContentByte canvas = stamper.getOverContent(i);
//                canvas.showTextAligned(PdfContentByte.ALIGN_CENTER, "", 15, 15, 0);
//                canvas.set
                canvas.saveState();
                //设置颜色
                canvas.setColorFill(BaseColor.WHITE);
                //解析坐标
                double x = Double.valueOf(xy.split("--")[0]);
                double y = Double.valueOf(xy.split("--")[1]) - 10;
                //后面2个参数分别是宽高
                canvas.rectangle(x, y, 450, 100);
                canvas.fill();
                canvas.restoreState();
            }
            stamper.close();
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

补充:

private  AttachRecords complex_fill_pod_excel_to_pdf(KeyVo keyVo, List<BaseVo> detailInfo, ResourceLoader resourceLoader, String fileName) throws IOException {
        log.info("complex_fill_pod_excel_to_pdf input param,keyVo:{},detailInfo:{},fileName:{}", JSONObject.toJSONString(keyVo),
                JSONObject.toJSONString(detailInfo), fileName);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
            // {} 代表普通变量 {.} 代表是list的变量
            InputStream inputStream = resourceLoader.getResource(BOL_POD_TEMPLATE_NEW_FORMAT).getInputStream();
            ExcelWriter excelWriter = EasyExcel.write(bos).withTemplate(inputStream).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            // 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行,然后下面的数据往后移动。默认 是false,会直接使用下一行,如果没有则创建。
            // forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了,所以慎用
            // 简单的说 如果你的模板有list,且list不是最后一行,下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
            // 如果数据量大 list不是最后一行 参照下一个
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
            excelWriter.fill(detailInfo, fillConfig, writeSheet);
            excelWriter.fill(keyVo, writeSheet);
            excelWriter.finish();



            if (ObjectUtil.isEmpty(bos) || bos.size() == 0){
                log.error("complex_fill_pod_excel_to_pdf error bos is null");
                return null;
            }

            String middleFileName = UUID.randomUUID().toString();
            // 生成原excel文件
            String sourceExcelFileName = "excel-" + middleFileName + ".xlsx";
            AttachRecordsThinVo attachRecordsThinVo = attachRecordsService.directSaveFile(sourceExcelFileName, bos.toByteArray());
            if (ObjectUtil.isEmpty(attachRecordsThinVo)){
                log.error("attachRecordsThinVo is null");
                return null;
            }

            // 转成pdf
            String destPdfFileName = "temp-" + middleFileName + ".pdf";
            AsposePdfUtil.excel2pdf(attachRecordsThinVo.getDirectoryName().concat(sourceExcelFileName),
                    attachRecordsThinVo.getDirectoryName().concat(destPdfFileName), null);

            // 移除水印
            String afterDestPdfFileName = "formal-" + middleFileName + ".pdf";
            AsposePdfUtil.replaceStr(attachRecordsThinVo.getDirectoryName().concat(destPdfFileName),
                    attachRecordsThinVo.getDirectoryName().concat(afterDestPdfFileName),
                    "Evaluation Only. Created with Aspose.Cells for Java.Copyright 2003 - 2023 Aspose Pty Ltd.");

            // 本地生成的文件,上传到阿里oss
            AttachRecords attachRecords = attachRecordsService.uploadAttachRecords(fileName,
                    attachRecordsThinVo.getDownloadDirectoryName().concat(afterDestPdfFileName),
                    FileUtils.readFileToByteArray(new File(attachRecordsThinVo.getDirectoryName().concat(afterDestPdfFileName))));

            log.info("complex_fill_pod_excel_to_pdf result attachRecords:{}",JSONObject.toJSONString(attachRecords));
            return attachRecords;
        } catch (Exception e) {
            log.error("complex_fill_pod_excel_to_pdf error!", e);
            e.printStackTrace();
            throw new ApiException(ResultCode.FAULT);
        } finally {
            bos.close();
        }
    }

到此这篇关于Java轻松实现Excel转PDF的实战指南的文章就介绍到这了,更多相关Java Excel转PDF内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解Spring依赖注入的三种方式以及优缺点

    详解Spring依赖注入的三种方式以及优缺点

    IoC 和 DI 是 Spring 中最重要的两个概念,其中 IoC(Inversion of Control)为控制反转的思想,而 DI(Dependency Injection)依赖注入为其(IoC)具体实现。那么 DI 实现依赖注入的方式有几种?这些注入方式又有什么不同?本文就来和大家一起详细聊聊
    2022-08-08
  • SpringBoot2如何集成Elasticsearch6.x(TransportClient方式)

    SpringBoot2如何集成Elasticsearch6.x(TransportClient方式)

    这篇文章主要介绍了SpringBoot2如何集成Elasticsearch6.x(TransportClient方式)问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • Spring Cloud之注册中心Nacos的使用详解

    Spring Cloud之注册中心Nacos的使用详解

    本文介绍SpringCloud Alibaba中的Nacos组件,对比了Nacos与Eureka的区别,展示了如何在项目中引入SpringCloud Alibaba和Nacos,并配置负载均衡,通过实际操作,验证了服务注册和负载均衡的功能,感兴趣的朋友一起看看吧
    2025-03-03
  • Spring boot2基于Mybatis实现多表关联查询

    Spring boot2基于Mybatis实现多表关联查询

    这篇文章主要介绍了Spring boot2基于Mybatis实现多表关联查询,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • logback的UNDEFINED_PROPERTY属性源码执行流程解读

    logback的UNDEFINED_PROPERTY属性源码执行流程解读

    这篇文章主要为大家介绍了logback的UNDEFINED_PROPERTY属性源码执行流程解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • 实例讲解Java的MyBatis框架对MySQL中数据的关联查询

    实例讲解Java的MyBatis框架对MySQL中数据的关联查询

    这里我们来以实例讲解Java的MyBatis框架对MySQL中数据的关联查询,包括一对多、多对一的关联查询以及自身关联映射的方法等,需要的朋友可以参考下
    2016-06-06
  • IDEA git版本回滚使用解读

    IDEA git版本回滚使用解读

    这篇文章主要介绍了Git的分区和回滚操作,包括工作区、暂存区和版本库的概念,以及如何在不同状态下进行回滚操作,如未commit、commit未push、已commit但未push以及已commit并push的情况
    2025-10-10
  • Hystrix Turbine聚合监控的实现详解

    Hystrix Turbine聚合监控的实现详解

    微服务架构下,⼀个微服务往往部署多个实例,如果每次只能查看单个实例的监控,就需要经常切换很不⽅便,在这样的场景下,我们可以使⽤ Hystrix Turbine 进⾏聚合监控,它可以把相关微服务的监控数据聚合在⼀起,便于查看
    2022-09-09
  • jmeter接口测试之使用rsa算法加密解密的代码

    jmeter接口测试之使用rsa算法加密解密的代码

    这篇文章主要介绍了jmeter接口测试-使用rsa加密解密算法,部分接口采用了rsa加密算法,我们的jmeter 也是可以直接拿来调用的,不需要开发配合去掉加密代码,需要的朋友可以参考下
    2022-03-03
  • Maven依赖冲突问题及解决过程

    Maven依赖冲突问题及解决过程

    文章主要讨论Maven依赖冲突问题,及提供解决方法,首先描述了依赖冲突现象的nd导致类NoClassDefFoundError的情况;然后介绍了查找冲突包的方法,最后总结了Maven依赖管理的几种策略,包括依赖调解、依赖排除和依赖范围控制;强调了合理配置POM文件的重要性
    2026-04-04

最新评论