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

简介: 这篇文章介绍了如何在Spring Boot项目中整合iTextPDF库来导出PDF文件,包括写入大文本和HTML代码,并分析了几种常用的Java 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依赖```

        <!--生成pdf-->
        <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>
        <!--html xml 转为pdf-->
        <dependency>
            <groupId>com.itextpdf.tool</groupId>
            <artifactId>xmlworker</artifactId>
            <version>5.5.11</version>
        </dependency>
    

    ```

  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("<br>", "<br/>").replace("<hr>", "<hr/>").replace("<img>", "").replace("<param>", "").replace("<link>", "");//不支持单独标签
        p.parse(new ByteArrayInputStream(html.getBytes()));
        return elements;
    }

}

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 = "<html><body><p class=\"\" style=\"\">如果说荷兰是橙色的,那阿姆斯特丹就是缤纷的彩色。"+stringBuilder.toString()+"</p>  <p class=\"\" style=\"\"><strong>游玩建议</strong><br>游玩整个阿姆斯特丹大约需2-3天</p></body></html>";
            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. 浏览器请求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. 请求:http://localhost:8084/pdf/createPdfDownload
  2. 结果:
    在这里插入图片描述
  3. 内容:
    在这里插入图片描述

四、基础知识学习

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

使用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

相关文章
|
19天前
|
安全 Java 应用服务中间件
Spring Boot + Java 21:内存减少 60%,启动速度提高 30% — 零代码
通过调整三个JVM和Spring Boot配置开关,无需重写代码即可显著优化Java应用性能:内存减少60%,启动速度提升30%。适用于所有在JVM上运行API的生产团队,低成本实现高效能。
125 3
|
4月前
|
监控 Java 数据安全/隐私保护
阿里面试:SpringBoot启动时, 如何执行扩展代码?你们项目 SpringBoot 进行过 哪些 扩展?
阿里面试:SpringBoot启动时, 如何执行扩展代码?你们项目 SpringBoot 进行过 哪些 扩展?
|
4月前
|
前端开发 JavaScript
个人征信电子版无痕修改, 个人信用报告pdf修改,js+html+css即可实现【仅供学习用途】
本代码展示了一个信用知识学习系统的前端实现,包含评分计算、因素分析和建议生成功能。所有数据均为模拟生成
|
6月前
精美按钮式广告代码HTML分享
精美按钮式广告代码HTML分享
124 4
|
4月前
|
人工智能 文字识别 自然语言处理
熊猫 OCR 识别软件下载,支持截图 OCR、PDF 识别、多语言翻译的免费全能工具,熊猫OCR识别
本文介绍了几款实用的图文识别软件,包括熊猫OCR、Umi-OCR和天若OCR_本地版。熊猫OCR功能强大,支持多窗口操作、AI找图找色、OCR识别等;Umi-OCR免费且高效,具备截图OCR、批量处理等功能;天若OCR界面简洁,适合快速文字识别。文章还提供了下载链接及软件特点、界面展示等内容,便于用户根据需求选择合适的工具。
364 36
|
4月前
|
Java 数据库连接 数据库
Spring boot 使用mybatis generator 自动生成代码插件
本文介绍了在Spring Boot项目中使用MyBatis Generator插件自动生成代码的详细步骤。首先创建一个新的Spring Boot项目,接着引入MyBatis Generator插件并配置`pom.xml`文件。然后删除默认的`application.properties`文件,创建`application.yml`进行相关配置,如设置Mapper路径和实体类包名。重点在于配置`generatorConfig.xml`文件,包括数据库驱动、连接信息、生成模型、映射文件及DAO的包名和位置。最后通过IDE配置运行插件生成代码,并在主类添加`@MapperScan`注解完成整合
675 1
Spring boot 使用mybatis generator 自动生成代码插件
|
6月前
|
人工智能 自然语言处理 算法
科研论文翻译神器!BabelDOC:开源AI工具让PDF论文秒变双语对照,公式图表全保留
BabelDOC 是一款专为科学论文设计的开源AI翻译工具,采用先进的无损解析技术和智能布局识别算法,能完美保留原文格式并生成双语对照翻译。
1951 67
科研论文翻译神器!BabelDOC:开源AI工具让PDF论文秒变双语对照,公式图表全保留
|
5月前
|
人工智能 自然语言处理 安全
CodeBuddy 开发本地 PDF 转图工具
市场上的 PDF 转图片工具存在收费昂贵、功能有限、隐私安全风险等痛点,而使用 CodeBuddy 实现的本地 PDF 批量转图片工具可以有效解决这些问题。CodeBuddy 的强大编程能力让我们可以快速开发出满足需求的工具,而且工具可以在本地运行,保证了文件的隐私安全。此外,工具还支持批量处理和自定义功能,提高了工作效率。如果你也有 PDF 转图片的需求,不妨尝试使用 CodeBuddy 来实现一个属于自己的工具。
150 11
|
5月前
|
人工智能 算法 安全
使用CodeBuddy实现批量转换PPT、Excel、Word为PDF文件工具
通过 CodeBuddy 实现本地批量转换工具,让复杂的文档处理需求转化为 “需求描述→代码生成→一键运行” 的极简流程,真正实现 “技术为效率服务” 的目标。感兴趣的快来体验下把
179 10
|
4月前
|
Java 调度 流计算
基于Java 17 + Spring Boot 3.2 + Flink 1.18的智慧实验室管理系统核心代码
这是一套基于Java 17、Spring Boot 3.2和Flink 1.18开发的智慧实验室管理系统核心代码。系统涵盖多协议设备接入(支持OPC UA、MQTT等12种工业协议)、实时异常检测(Flink流处理引擎实现设备状态监控)、强化学习调度(Q-Learning算法优化资源分配)、三维可视化(JavaFX与WebGL渲染实验室空间)、微服务架构(Spring Cloud构建分布式体系)及数据湖建设(Spark构建实验室数据仓库)。实际应用中,该系统显著提升了设备调度效率(响应时间从46分钟降至9秒)、设备利用率(从41%提升至89%),并大幅减少实验准备时间和维护成本。
272 0