• excel模板报表转PDF下载


    最近有一个需求,需要根据excel模板PDF报表;需要先根据excel模板生成excel文件,再由excel生成pdf文件,最后下载功;

    生成excel报表

    使用easypoi组件,详细可参考文档中excel模板部分;

    使用方法概述

    该方式的优势为样式与模板样式完全一致,可以实现单值属性与列表遍历;

    • 在excel模板中修改单元格内容为相应的easypoi支持的表达式;
    • 定义TemplateParam(模板属性)和数据属性;
    • 调用静态方法:ExcelExportUtil.exportExcel

    excel生成PDF报表

    实现方式种类

    IText

    纯JAVA实现的PDF生成方法,跨平台,缺点也很明显:API比较难用,同时很难处理Excel的样式;

    OpenOffice
    • 导入jar包: com.artofsolving-jodconverter

    • openOffice监听端口:soffice.exe -headless -accept="socket,host=%s,port=%s;urp;" -nofirststartwizard

    • 使用openOffice转换为PDF

                //连接
                var conn = new SocketOpenOfficeConnection(hostname,port);
                conn.connect();
                //转换
                converter = new OpenOfficeDocumentConverter(conn);
                converter.convert(docFile,pdfFile);
                //关闭连接
                conn.disconnect();
    

    优势: 跨平台;
    缺点: openOffice转换成的PDF在一定程度失真,比如excel边框自动加粗等,某一些样式不支持等,但是linux服务器上的唯一选择.

    windowOffice 或 wps

    • 导入jar包: jacob-1.19.zip

    • 安装windowOffice或wps;

    • 转换:

                //office命令
                 ActiveXComponent app = new ActiveXComponent("Excel.Application");
                //Wps方式
                app = new ActiveXComponent("KET.Application");
                app.setProperty("Visible", false);
                Dispatch excels = app.getProperty("Workbooks").toDispatch();
                excel = Dispatch.call(excels, "Open", path, false, true).toDispatch();
                Dispatch.call(excel, "ExportAsFixedFormat", 0, pdfAbsPath);
    

    优点: 完美的样式;
    缺点: 仅支持window服务器;

    文件下载

    后端下载基础代码

    response.setCharacterEncoding(CharsetUtil.UTF_8);
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition","attachment; filename=" + fileName);
            response.setContentLengthLong(pdfFile.length());
    

    注意事项

    • 不同浏览器支持的文件名编码格式不同,大部分使用UrlEnocde编码即可,safari浏览器需要ISO8859-1的字符串编码

    前端处理

    前端使用js下载blob,并创建blob的下载地址
    config.responseType = "blob";
    let blob = new Blob([response.data],{type: 'application/pdf'}); //创建一个blob对象
    let downloadName = response.headers["content-disposition"].split(";")[1].split("filename=")[1];
    let a = document.createElement('a');
    let url = URL.createObjectURL(blob)
    a.href = url; // response is a blob
    a.download = downloadName;  //文件名称
    a.style.display = 'none';
    document.body.appendChild(a);
    a.click();
    a.remove();
    

    缺点: 在safari中出现下载文件名为:known的异常;

    使用第三方组件

    该方法是上一种方法的扩展,不自己创建a标签,使用file-sever组件,只需要传入blob对象即可;

     FileSaver.saveAs(blob, downloadName);
    
    

    缺点: 在safari中出现下载文件名为:known的异常;

    前端创建真实的后端下载地址

    let a = document.createElement('a');
    a.href = url; // 直接为后端的url;
    a.style.display = 'none';
    document.body.appendChild(a);
    a.click();
    a.remove();
    

    优点:理论上所有浏览器均可正确识别文件名信息;
    缺点: 因为不是通过ajax请求的后端接口,在前后端分离系统中要单独处理权限验证的东西(如token等);

  • 相关阅读:
    Java 基本数据类型
    关于 Java 安装配置文件总结
    Day01
    关于自律!
    Java
    Java
    一年软件开发工作有感!
    如何解决文档复制时候禁止复制限制
    tensorflow tf.keras概述
    jupyter使用说明书
  • 原文地址:https://www.cnblogs.com/417xiaoliu/p/11039102.html
Copyright © 2020-2023  润新知