zoukankan      html  css  js  c++  java
  • springboot集成itext根据模板导出PDF

    项目需要根据一个已知的模板文档,取数据然后填充空格。

    先制作word版模板,然后另存为pdf格式,转换后使用Adobe Acrobat Pro添加域,生成PDF模板。

    利用itext读取模板,填充数据,下载导出。

    参考大神链接:https://blog.csdn.net/tyc_054600/article/details/104060362

    具体步骤:

    1、pom引用

                <dependency>
    			<groupId>com.itextpdf</groupId>
    			<artifactId>itextpdf</artifactId>
    			<version>5.5.11</version>
    		</dependency>
    
    		<dependency>
    			<groupId>com.itextpdf</groupId>
    			<artifactId>itext-asian</artifactId>
    			<version>5.2.0</version>
    		</dependency>
    

      2、创建PdfUtil类

    package com.ruoyi.common.utils.itext;
    
    import com.itextpdf.text.Document;
    import com.itextpdf.text.DocumentException;
    import com.itextpdf.text.PageSize;
    import com.itextpdf.text.pdf.*;
    import com.ruoyi.common.config.Global;
    import java.net.URLEncoder;
    import org.apache.commons.io.IOUtils;
    
    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    import java.util.Map;
    
    /**
     * @Description
     * @auther Tian
     * @Date 2020/4/11 13:28
     **/
    public class PdfUtil {
        /**
         * 利用模板生成pdf保存到某路径下
         */
        public static void pdfOut(String modalFilename,String newFilename,Map<String, Object> inputMap) {
    
            // 生成的新文件路径
            String path0 = Global.getReportPath();
            File f = new File(path0);
    
            if (!f.exists()) {
                f.mkdirs();
            }
            // 模板路径
            String templatePath = Global.getReportPath()+modalFilename;
            // 创建文件夹
            String newPdfPath = Global.getReportPath()+newFilename;
            File file = new File(templatePath);
            if (!file.exists()) {
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            File file1 = new File(newPdfPath);
            if (!file1.exists()) {
                try {
                    file1.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            PdfReader reader;
            FileOutputStream out;
            ByteArrayOutputStream bos;
            PdfStamper stamper;
            try {
                String path = "C:/WINDOWS/Fonts/simsun.ttc,0";//windows里的字体资源路径
                BaseFont bf = BaseFont.createFont(path, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                // 输出流
                out = new FileOutputStream(newPdfPath);
                // 读取pdf模板
                reader = new PdfReader(templatePath);
                bos = new ByteArrayOutputStream();
                stamper = new PdfStamper(reader, bos);
                AcroFields form = stamper.getAcroFields();
                //文字类的内容处理
                Map<String, String> datemap = (Map<String, String>) inputMap.get("dateMap");
                form.addSubstitutionFont(bf);
                for (String key : datemap.keySet()) {
                    String value = datemap.get(key);
                    form.setField(key, value);
                }
                stamper.setFormFlattening(false);
                stamper.close();
                Document doc = new Document(PageSize.LETTER.rotate());//pdf横向打开
                doc.setPageSize(PageSize.A4);
                PdfCopy copy = new PdfCopy(doc, out);
                doc.open();
                PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
                copy.addPage(importPage);
                doc.close();
                out.close();
                reader.close();
            } catch (IOException | DocumentException e) {
                System.out.println(e);
            }
    
        }
    
        /**
         * 利用模板生成pdf导出
         */
        public static void pdfExport(String modalFilename,String newFilename, HttpServletResponse response,Map<String, Object> inputMap) {
    
            // 生成的新文件路径
            String path0 = Global.getReportPath();
            File f = new File(path0);
    
            if (!f.exists()) {
                f.mkdirs();
            }
            // 模板路径
            String templatePath = Global.getReportPath()+modalFilename;
    
            File file = new File(templatePath);
            if (!file.exists()) {
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            PdfReader reader;
            ByteArrayOutputStream bos;
            PdfStamper stamper;
            OutputStream out = null;
            try {
                Map<String, String> datemap = (Map<String, String>) inputMap.get("dateMap");
                String path = "C:/WINDOWS/Fonts/simsun.ttc,0";//windows里的字体资源路径
                BaseFont bf = BaseFont.createFont(path, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                // 输出流
                response.setContentType("application/pdf");
                response.setHeader("Content-Disposition",
                        "attachment;fileName=" + URLEncoder.encode(newFilename, "UTF-8"));
                out = new BufferedOutputStream(response.getOutputStream());
                // 读取pdf模板
                reader = new PdfReader(templatePath);
                bos = new ByteArrayOutputStream();
                stamper = new PdfStamper(reader, bos);
                AcroFields form = stamper.getAcroFields();
                //文字类的内容处理
                form.addSubstitutionFont(bf);
                for (String key : datemap.keySet()) {
                    String value = datemap.get(key);
                    form.setField(key, value);
                }
                stamper.setFormFlattening(false);
                stamper.close();
                Document doc = new Document(PageSize.LETTER.rotate());//pdf横向打开
                doc.setPageSize(PageSize.A4);
                PdfCopy copy = new PdfCopy(doc, out);
                doc.open();
                PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
                copy.addPage(importPage);
                doc.close();
                reader.close();
            } catch (IOException | DocumentException e) {
                System.out.println(e);
            } finally {
                try {
                    assert out != null;
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * 读取本地pdf,这里设置的是预览
         */
        public static void readPdf(String filename,HttpServletResponse response) {
            response.reset();
            response.setContentType("application/pdf");
            try {
                File file = new File(Global.getReportPath()+filename);
                FileInputStream fileInputStream = new FileInputStream(file);
                OutputStream outputStream = response.getOutputStream();
                IOUtils.write(IOUtils.toByteArray(fileInputStream), outputStream);
                response.setHeader("Content-Disposition",
                        "inline; filename= "+filename);
                outputStream.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

      3、创建Controller

     @GetMapping("/downPdf")
        public void downloadPDF(HttpServletRequest request, HttpServletResponse response) throws Exception {
            //PdfUtil.pdfExport("report1.pdf",response);;//导出文件
            Map<String, Object> dataMap=new HashMap<>();
            Map<String,String> dataMap1=new HashMap<>();
            dataMap1.put("name1","overs202004111610");
            dataMap.put("dateMap",dataMap1);
            //PdfUtil.pdfOut("report1.pdf","report2.pdf",dataMap);//生成文件
            //PdfUtil.readPdf("report2.pdf",response);//预览文件
    		PdfUtil.pdfExport(modalFilename, newFilename,response,dataMap);;//导出文件
        }
    

      4、页面添加下载按钮,如果没有form可JS添加

     function downPdf(){
            var url = '/system/reportexport/downPdf/';
            var form = $("<form>");//定义一个form表单
            form.attr("style", "display:none");
            form.attr("target", "");
            form.attr("method", "get");  //请求类型
            form.attr("action", url);   //请求地址
            $("body").append(form);//将表单放置在web中
    
            form.submit();//表单提交
           }
    

      5、制作模板

    在指定位置添加pdf模板,先用word编辑好要到处的模板,另存为可以存为PDF格式。
    转换为PDF后使用Adobe Acrobat Pro(网上有破解版,下载时注意不要附加其他的软件下载),打开要使用的PDF,
    表单->添加或编辑域->修改域名(域名即为待填充的字段名称)

    此时会默认添加很多域,可以手动增加或删除域,双击域可修改域的名称、可读属性、字体大小和样式。

    6、字体问题

    中文问题:
    String path = "C:/WINDOWS/Fonts/simsun.ttc,0";//windows里的字体资源路径
    BaseFont bf = BaseFont.createFont(path, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    有些中文显示不全 企业名称显示企名称,但是预览点击时显示企业名称,预览和打印显示企名称
    考虑是字体包的问题,替换字体包 为仿宋 String path = "C:/WINDOWS/Fonts/simsun.ttc,0";//windows里的字体资源路径,正常显示

    本地查看电脑所带字体:C:/WINDOWS/Fonts,这个文件夹下的字体,右键打开属性,会看到文件名。个人建议使用宋体,使用windows自带字体,这样兼容性会高很多。

    参考大神链接:

    1、https://www.cnblogs.com/whalesea/p/11752086.html

    2、https://www.cnblogs.com/whalesea/p/11714681.html

    7、下载后使用AdobeReader打开会报错,缺少字体包
    可以使用右击,选择浏览器打开
    或者是AdobeReader字体包的原因
    使用Adobe Acrobat Pro域编辑时,选择域属性,选择字体为生成文件选用的字体,windows系统自带字体包含宋体,使用宋体可以


    8、下载后不可编辑
    域属性选择只读,否则下载的文件就可以编辑,在AdobeReader中打开这些位置还会显示蓝色。


    9、增加权限
    https://www.cnblogs.com/matrix-zhu/p/6305944.html

  • 相关阅读:
    Java 中文 乱码问题
    JQuery 操作 radio 被坑一例
    标准I/O库之打开和关闭流
    标准I/O库之缓冲
    标准I/O库之标准输入、标准输出和标准出错
    标准I/O库之流和FILE对象
    文件和目录之文件访问权限位小结
    文件和目录之设备特殊文件
    文件和目录之chdir、fchdir和getcwd函数
    文件和目录之读目录
  • 原文地址:https://www.cnblogs.com/webttt/p/12854680.html
Copyright © 2011-2022 走看看