java Excel转Pdf

项目中遇到了导出pdf的问题,一开始采用ireport的形式,但是这东西他不兼容jdk1.8所以就放弃了,有没有什么好的方法直接将excel转成pdf输出呢?我也是在网上白嫖了一顿。

Aspose-Cells.jar他就来了。

只需要将jar包和去水印的license文件导入到项目中,再写几行代码就可以了。

相关jar包已经放到了网盘中,移步下载。

链接:下载jar包
提取码:dpak



import com.aspose.cells.*;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * excel转pdf
 * @description:xlsx转pdf
 */
public class ExcelToPdf {
    /**
     * 获取license 去除水印
     * @return
     */
    public static boolean getLicense() {
        boolean result = false;
        try {
            InputStream is = XLSXConvertToPDF.class.getClassLoader().getResourceAsStream("\\license.xml");
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * excel 转为pdf 输出。
     *
     * @param sourceFilePath  excel文件
     * @param desFilePathd  pad 输出文件目录
     */
    public static void excel2pdf(String sourceFilePath, String desFilePathd){
        if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
            return;
        }
        try {
            Workbook wb = new Workbook(sourceFilePath);// 原始excel路径

            FileOutputStream fileOS = new FileOutputStream(desFilePathd);
            PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();

            pdfSaveOptions.setOnePagePerSheet(true);//如果需要分页打印的话需要注释此行 

            //pdfSaveOptions.setAllColumnsInOnePagePerSheet(true);
            //如果 AllColumnsInOnePagePerSheet 为 true ,
            //则结果中一张表的所有列内容将仅输出到一页 宽度会被失效,
            //这样所有的列就都可以显示在每一页中,不会被截断了

            int[] autoDrawSheets={3};
            //当excel中对应的sheet页宽度太大时,在PDF中会拆断并分页。此处等比缩放。
            autoDraw(wb,autoDrawSheets);
            int[] showSheets={0};
            //隐藏workbook中不需要的sheet页。
            printSheetPage(wb,showSheets);
            wb.save(fileOS, pdfSaveOptions);
            fileOS.flush();
            fileOS.close();
            //System.out.println("转换PDF完毕!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置打印的sheet 自动拉伸比例
     * @param wb
     * @param page 自动拉伸的页的sheet数组
     */
    public static void autoDraw(Workbook wb,int[] page){
        if(null!=page&&page.length>0){
            for (int i = 0; i < page.length; i++) {
                wb.getWorksheets().get(i).getHorizontalPageBreaks().clear();
                wb.getWorksheets().get(i).getVerticalPageBreaks().clear();
            }
        }
    }


    /**
     * 隐藏workbook中不需要的sheet页。
     * @param wb
     * @param page 显示页的sheet数组
     */
    public static void printSheetPage(Workbook wb,int[] page){
        for (int i= 1; i < wb.getWorksheets().getCount(); i++)  {
            wb.getWorksheets().get(i).setVisible(false);
        }
        if(null==page||page.length==0){
            wb.getWorksheets().get(0).setVisible(true);
        }else{
            for (int i = 0; i < page.length; i++) {
                wb.getWorksheets().get(i).setVisible(true);
            }
        }
    }
}

下面测试:

@Test
void toPdf() {
   String path1 = "D:/pdfLoc/test.xlsx"; //现存的excel文件全路径 + 文件名 + 后缀
   String path2 = "D:/pdfLoc/test.pdf"; //要生成的pdf文件全路径 + 文件名 + 后缀
   ExcelToPdf.excel2pdf(path1,path2);
}

 效果图,随便写的,没搞样式,大家根据自己需求来。

 那么如何输出到浏览器下载呢?

此时已经知道了生成的pdf地址。

后端:

 response.setHeader("Content-Type", "application/json;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-disposition", "attachment;filename*="+ URLEncoder.encode(fileName,"UTF-8"));//默认Excel名称
        response.setHeader("Access-Control-Expose-Headers", "Content-disposition");

OutputStream os = response.getOutputStream();
            FileInputStream stream = new FileInputStream("D:/pdfLoc/test.pdf");//读取生成好的pdf
            byte[] buffer = new byte[4096];
            int n = 0;
            while (-1 != (n = stream.read(buffer))) {
                os.write(buffer, 0, n);
            }
            stream.close();
            os.flush();
            os.close();
           //只是列了这几行关键代码,具体业务具体分析

 前端处理:

axios({ // 用axios发送post请求
    method: 'post',
    url: _api, // 请求地址
    data: _param, // data参数
    responseType: 'arraybuffer', // 表明返回服务器返回的数据类型
    headers: { //
      'Content-Type': 'application/json;charset=utf-8'
    },
    // 表明返回服务器返回的数据类型
  }).then((res) => {
    //console.log('headers', res.headers)
    let fileName = decodeURI(res.headers['content-disposition'].split('=')[1]);
    let url = window.URL.createObjectURL(new Blob([res.data], { type: 'application/pdf' }))
    const a = document.createElement('a')
    a.style.display = 'none'
    a.download = fileName
    a.href = url
    a.click()
    if (document.body.contains(a)) {
      document.body.removeChild(a)
    }
  }).catch(function(error) {
    console.log("下载失败!");
  });

这样一套组合拳下来,基本就出来了。

Java中,将Excel文件换成PDF通常需要使用一些库来处理电子表格和生成PDF文档。Apache POI是一个常用的Java库,用于操作Microsoft Office格式(包括Excel),而iText或Flying Saucer等库则可以用来创建PDF文件。 以下是一个简单的步骤示例: 1. 引入所需的库依赖: - poi:`<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>最新版本</version> </dependency>` - iText或itextpdf:`<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>最新版本</version> </dependency>` 2. 使用POI读取Excel数据: ```java FileInputStream fis = new FileInputStream("input.xlsx"); HSSFWorkbook workbook = new HSSFWorkbook(fis); Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表 ``` 3. 将数据换为iText元素(如果使用iText): ```java PdfDocument pdfDoc = new PdfDocument(); for (Row row : sheet) { List<Cell> cells = row.Cells; for (Cell cell : cells) { String cellValue = cell.getStringCellValue(); // 添加到PDF的相应位置 } } ``` 4. 创建并写入PDF: ```java PdfPTable table = new PdfPTable(numberOfColumns); for (Row row : sheet) { PdfPCell cell = createTableCell(row); table.addCell(cell); } pdfDoc.add(table); try (OutputStream os = new FileOutputStream("output.pdf")) { pdfDoc.write(os); } ``` 5. 关闭资源: ```java workbook.close(); pdfDoc.close(); fis.close(); ``` 注意:这个过程可能会比较复杂,特别是处理表格样式和合并单元格等问题,实际操作时可能需要根据具体需求调整。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值