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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java动态方法调度实例分析

    java动态方法调度实例分析

    这篇文章主要介绍了java动态方法调度,结合实例形式对比分析了java的动态方法调度原理、使用方法与注意事项,需要的朋友可以参考下
    2016-06-06
  • java 中volatile和lock原理分析

    java 中volatile和lock原理分析

    这篇文章主要介绍了java 中volatile和lock原理分析的相关资料,需要的朋友可以参考下
    2017-03-03
  • mybatis实现mapper配置并查询数据的思路详解

    mybatis实现mapper配置并查询数据的思路详解

    这篇文章主要介绍了mybatis实现mapper配置并查询数据,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • 实战分布式医疗挂号系统登录接口整合阿里云短信详情

    实战分布式医疗挂号系统登录接口整合阿里云短信详情

    这篇文章主要为大家介绍了实战分布式医疗挂号系统登录接口整合阿里云短信详情,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>
    2022-04-04
  • Java中数组array和列表list相互转换

    Java中数组array和列表list相互转换

    这篇文章主要介绍了Java中数组array和列表list相互转换,在Java中,可以将数组(array)和列表(list)相互转换,但需要注意一些细节和限制,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-09-09
  • SpringBoot项目运行jar包启动的步骤流程解析

    SpringBoot项目运行jar包启动的步骤流程解析

    这篇文章主要介绍了SpringBoot项目运行jar包启动的步骤流程,本文分步骤通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2020-07-07
  • Spring中@Transactional注解关键属性和用法小结

    Spring中@Transactional注解关键属性和用法小结

    在Spring框架中,@Transactional 是一个注解,用于声明事务性的方法,它提供了一种声明式的事务管理方式,避免了在代码中直接编写事务管理相关的代码,本文给大家介绍@Transactional 注解的一些关键属性和用法,感兴趣的朋友一起看看吧
    2023-12-12
  • Java使用@Retryable注解实现HTTP请求重试

    Java使用@Retryable注解实现HTTP请求重试

    HTTP调用是Java应用与外部API进行交互时重要的访问方式之一,为了确保在遇到临时性问题时能自动重试,我们可以设计一个灵活的重试机制,在Java中,我们可以通过注解来实现这一功能,文将介绍如何使用注解@Retryable来实现HTTP调用的重试机制,需要的朋友可以参考下
    2024-10-10
  • spring boot使用sonarqube来检查技术债务

    spring boot使用sonarqube来检查技术债务

    今天小编就为大家分享一篇关于spring boot使用sonarqube来检查技术债务,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • 深入了解Java atomic原子类的使用方法和原理

    深入了解Java atomic原子类的使用方法和原理

    这篇文章主要介绍了深入了解Java atomic原子类的使用方法和原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,,需要的朋友可以参考下
    2019-06-06

最新评论