• spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具


    前言

    1. 项目背景:还是帮助老师做了一个项目,然后有一个功能,从ES中拿到数据,导出到PDF中,之前没有做过导出PDF,所以通过网上五花八门的资料学习,决定整合 itextpdf(也成为itext,4版本之前itext,之后就是itextpdf)来导出PDF,这里也做了一下记录,以便后续使用。
    2. itextpdf 官网:https://itextpdf.com/
    3. 5.x 版本的 api文档:https://itextpdf.com/resources/api-documentation/itext-5-java
    4. 7.x 版本的 api文档:https://itextpdf.com/resources/api-documentation/itext-7-java

    一、java 导出PDF 的几个工具

    从知乎上,找到下面这张照片,从点击次数可以看出,itext 处于首位,使用最多,依次是PDF Box、 JasperReports。剩下的就没有太过于了解了
    在这里插入图片描述

    1. PDF Box

    1. 官网:没有找到,有知道的朋友可以留言补上,感激
    2. 学习文档:http://www.vue5.com/pdfbox/pdfbox_quick_guide.html
    3. maven依赖:http://www.vue5.com/pdfbox/pdfbox_environment.html 最下面就是

    看学习文档的最左边发现,box的功能有点局限性,主要亮点 是分析、读取PDF,于我自己的需求(写入HTML)不大匹配,也是轻量级的,就pass掉了。
    但后来需求有改动,写入文本,也是可以考虑的,但就就没有探索了。

    2. JasperReports/jFreeReport导出 报表 PDF

    1. 请注意:JasperReport 和 jFreeReport 是两个开源工具
    2. JasperReports官网:https://community.jaspersoft.com/project/jasperreports-library
    3. jFreeReport官网:https://java-source.net/open-source/pdf-libraries/jfreereport
    4. 学习文档:
    5. maven 依赖:看下面的博文

    这个工具的最大的优点是写入报表到PDF中,也是很好的工具,但不适合我的需求,但在找资料的时候,也找到了一些不错的博文,放在下面以便学习

    1. 介绍itext 和JasperReports(主要)
    2. JFreeReport- Java报表工具
    3. JasperReport和jFreeReport的比较

    3. itextpdf 导出PDF(敲重点)

    这个工具是我本次需要所选择的工具,也是重点所讲的工具

    1. 官网:itextpdf 官网:https://itextpdf.com/
    2. 历史版本区别:网上能看到很多资料,一会儿itext,一会儿itextpdf,为啥嘞,接着看:
      itext.jar-(0.99-4.2.2)是旧版本,itextpdf.jar-(5.0以后的)是新版本,现在更是推出了7.x版本;两个是同一个东西,新版只不过某些api变了,学习成本没增加多少,网上一搜一大把新版的api使用,以前旧的系统类似EJB系统大部分用的itext.jar,现在新的系统比如用spring搭起来的系统用的都是itextpdf.jar
    3. 5.x 学习文档
    4. 7.x 学习文档

    从网上找了几个基础入门的博文链接,写的也不错,放下面啦

    1. https://blog.csdn.net/qq_26296197/article/details/79348081
    2. Itextpdf5 基础知识:https://blog.csdn.net/qq_39181568/article/details/80003903
    3. Itextpdf5 基础知识:https://blog.csdn.net/weixin_43164309/article/details/120068686

    二、springboot整合itextpdf

    1. springboot项目直接创建即可
    2. 导入maven依赖
              
              <dependency>
                  <groupId>com.itextpdfgroupId>
                  <artifactId>itextpdfartifactId>
                  <version>5.5.11version>
              dependency>
              
              <dependency>
                  <groupId>com.itextpdfgroupId>
                  <artifactId>itext-asianartifactId>
                  <version>5.2.0version>
              dependency>
              
              <dependency>
                  <groupId>com.itextpdf.toolgroupId>
                  <artifactId>xmlworkerartifactId>
                  <version>5.5.11version>
              dependency>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
    3. springboot整合itextpdf 到此结束,接下来就是学习和导出PDF啦

    三、两个案例

    两个接口可以直接使用

    1. 写入HTML到PDF需要自定义工具类

    package com.example.demo_fengfanli.utils;
    
    import com.itextpdf.text.Font;
    import com.itextpdf.text.pdf.BaseFont;
    import com.itextpdf.tool.xml.ElementList;
    import com.itextpdf.tool.xml.XMLWorker;
    import com.itextpdf.tool.xml.XMLWorkerFontProvider;
    import com.itextpdf.tool.xml.XMLWorkerHelper;
    import com.itextpdf.tool.xml.css.CssFile;
    import com.itextpdf.tool.xml.css.StyleAttrCSSResolver;
    import com.itextpdf.tool.xml.html.CssAppliers;
    import com.itextpdf.tool.xml.html.CssAppliersImpl;
    import com.itextpdf.tool.xml.html.Tags;
    import com.itextpdf.tool.xml.parser.XMLParser;
    import com.itextpdf.tool.xml.pipeline.css.CSSResolver;
    import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
    import com.itextpdf.tool.xml.pipeline.end.ElementHandlerPipeline;
    import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
    import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
    
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    
    public class MyXMLWorkerHelper {
    
        public static class MyFontsProvider extends XMLWorkerFontProvider {
            public MyFontsProvider() {
                super(null, null);
            }
    
            @Override
            public Font getFont(final String fontname, String encoding, float size, final int style) {
                try {
                    BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);//中文字体
                    return new Font(bfChinese, size, style);
                } catch (Exception ex) {
                    return new Font(Font.FontFamily.UNDEFINED, size, style);
                }
            }
        }
    
        public static ElementList parseToElementList(String html, String css) throws IOException {
            // CSS
            CSSResolver cssResolver = new StyleAttrCSSResolver();
            if (css != null) {
                CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream(css.getBytes()));
                cssResolver.addCss(cssFile);
            }
    
            // HTML
            MyFontsProvider fontProvider = new MyFontsProvider();
            CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
            HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
            htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
            htmlContext.autoBookmark(false);
    
            // Pipelines
            ElementList elements = new ElementList();
            ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
            HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext, end);
            CssResolverPipeline cssPipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
    
            // XML Worker
            XMLWorker worker = new XMLWorker(cssPipeline, true);
            XMLParser p = new XMLParser(worker);
            html = html.replace("
    "
    , "
    "
    ).replace("
    "
    , "
    "
    ).replace("", "").replace("", "").replace("", "");//不支持单独标签 p.parse(new ByteArrayInputStream(html.getBytes())); return elements; } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    2. html 写入pdf 到本地

    这个就是将生成的PDF直接放到了

        @GetMapping("/createPdfSaveFile")
        public String createPdfSaveFile(){
            String path = "d:\\upload\\textffff.pdf";
            try {
                // 判断路径中文件夹是否存在,不存在则自动创建,防止因为文件夹不存在而报错
                creatNewFile(path);
                // 创建文档
                Document document = new Document(PageSize.A4,60,60,15,40);
                // 创建输入流
                PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(path));
                document.open();
    
                // 制作大文本数据
                StringBuilder stringBuilder = new StringBuilder();
                for (int i = 0; i <= 100; i++){
                    stringBuilder.append("如果说荷兰是橙色的,那阿姆斯特丹就是缤纷的彩色。");
                }
                // 添加数据
                String pocketDescription = "

    如果说荷兰是橙色的,那阿姆斯特丹就是缤纷的彩色。"+stringBuilder.toString()+"

    游玩建议
    游玩整个阿姆斯特丹大约需2-3天

    "
    ; Paragraph context = new Paragraph(); // html 的处理 ElementList elementList = MyXMLWorkerHelper.parseToElementList(pocketDescription, null); // 写入到 段落 Paragraph for (Element element : elementList) { context.add(element); } context.setSpacingBefore(10f); document.add(context); document.close(); writer.close(); } catch (IOException e) { throw new RuntimeException(e); } catch (DocumentException e) { throw new RuntimeException(e); } return "ok"; } /** * 检查是否存在文件夹并创建 * * @param path * @throws IOException */ public static File creatNewFile(String path) throws IOException { File file = new File(path); File fileParent = file.getParentFile(); if (!fileParent.exists()) { fileParent.mkdirs(); } file.createNewFile(); return file; }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    1. 浏览器请求http://localhost:8084/pdf/createPdfSaveFile,如下:
      在这里插入图片描述
    2. 资源管理器
      在这里插入图片描述
    3. PDF
      在这里插入图片描述

    3. 文本写到PDF下载使用

        @GetMapping("/createPdfDownload")
        public String createPdfToDownload(HttpServletResponse response) throws IOException {
    
            // 生成 pdf 名称
            Date date = new Date();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String str = simpleDateFormat.format(date);
            String datetime = str.replace("-", "").replace(" ", "").replace(":","");
            String filename = "pdf_"+datetime+"_content.pdf";
    
            // 创建PDF
            Document document = new Document(PageSize.A4,60,60,15,40);
            try {
                // 设置响应头,控制浏览器下载该文件
                response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
                //常用的有paragraph段落、phrase语句块、chunk最小单位块
                OutputStream out = response.getOutputStream();
                PdfWriter writer = PdfWriter.getInstance(document, out);
    
                // 打开文档
                document.open();
                BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                for(int n = 0; n<2; n++){
                    // 添加文字水印
                    PdfContentByte cb = writer.getDirectContent();
                    cb.beginText(); // 开始
                    // 设置透明度
                    PdfGState gs = new PdfGState();
                    gs.setFillOpacity(0.2f);
                    cb.setGState(gs);
                    cb.setFontAndSize(bfChinese,100);
                    cb.showTextAligned(Element.ALIGN_CENTER, "北京交通大学", 340, 410 , 60);
                    cb.endText(); // 结束
    
                    // 添加标题
                    //通过Font去设置字体的基本属性:大小,加粗等等
                    Font font  = new Font(bfChinese, 15, Font.NORMAL, BaseColor.BLACK);
                    // 创建段落
                    Paragraph title = new Paragraph("我是 title ", font);
                    title.setAlignment(Element.ALIGN_CENTER);
                    title.setSpacingBefore(40f);
                    document.add(title);
    
                    // 制作大文本数据
                    StringBuilder stringBuilder = new StringBuilder();
                    for (int i = 0; i <= 100; i++){
                        stringBuilder.append("如果说荷兰是橙色的,那阿姆斯特丹就是缤纷的彩色。");
                    }
                    Font font1  = new Font(bfChinese, 10, Font.NORMAL, BaseColor.BLACK);
                    Paragraph context = new Paragraph(stringBuilder.toString(), font1);
                    context.setFirstLineIndent(20);
                    context.setLeading(12);
                    context.setSpacingBefore(10f);
                    document.add(context);
    
                    // 开启新的一页
                    document.newPage();
                    //显示空内容的页
                    writer.setPageEmpty(false);
                }
                // 关闭流
                document.close();
                writer.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (DocumentException e) {
                throw new RuntimeException(e);
            }
            return "ok";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    1. 请求:http://localhost:8084/pdf/createPdfDownload
    2. 结果:
      在这里插入图片描述
    3. 内容:
      在这里插入图片描述

    四、基础知识学习

    这里没时间写啦,可以看2.3中的其他博主的博文,也写的挺好。

    itextpdf 到处pdf 创建下载链接:https://blog.csdn.net/man_18483633325/article/details/116988895

    使用itex生成pdf文件并下载总结:https://blog.csdn.net/qxy15997826736/article/details/125585884

    itextpdf 写入 html
    http://t.zoukankan.com/mvilplss-p-5646675.html
    https://blog.csdn.net/lingbo89/article/details/76187582

  • 相关阅读:
    SAP ME21N\ME22N\ME23N采购订单增强:抬头、行项目取值处理
    阿里直呼真省钱!全网首发IntelliJ IDEA应用实战手册竟遭哄抢
    BUG:编写springboot单元测试,自动注入实体类报空指针异常
    c语言-数据结构-堆
    Spring Cloud Gateway整合Swagger聚合微服务系统API文档(非Zuul)
    ElasticSearch Python API教程
    MySQL高级六:权限管理
    final关键字
    [MATLAB]进阶绘图
    用c语言来实现一个寻找迷宫出口的算法
  • 原文地址:https://blog.csdn.net/qq_40036754/article/details/127435226