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

相关文章
|
3天前
|
人工智能 文字识别 数据挖掘
MarkItDown:微软开源的多格式转Markdown工具,支持将PDF、Word、图像和音频等文件转换为Markdown格式
MarkItDown 是微软开源的多功能文档转换工具,支持将 PDF、PPT、Word、Excel、图像、音频等多种格式的文件转换为 Markdown 格式,具备 OCR 文字识别、语音转文字和元数据提取等功能。
51 9
MarkItDown:微软开源的多格式转Markdown工具,支持将PDF、Word、图像和音频等文件转换为Markdown格式
|
20天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
38 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
Documind:开源 AI 文档处理工具,将 PDF 转换为图像提取结构化数据
Documind 是一款利用 AI 技术从 PDF 中提取结构化数据的先进文档处理工具,支持灵活的本地或云端部署。
94 8
Documind:开源 AI 文档处理工具,将 PDF 转换为图像提取结构化数据
|
1月前
|
缓存 监控 Java
|
1月前
|
缓存 监控 Java
|
1月前
|
前端开发 API
前端界面生成PDF并导出下载
【10月更文挑战第21天】利用合适的第三方库,你可以在前端轻松实现界面生成 PDF 并导出下载的功能,为用户提供更方便的文档分享和保存方式。你还可以根据具体的需求进一步优化和定制生成的 PDF 文件,以满足不同的业务场景要求。
|
2月前
|
监控 Java 开发者
掌握SpringBoot扩展接口:提升代码优雅度的16个技巧
【10月更文挑战第20天】 SpringBoot以其简化配置和快速开发而受到开发者的青睐。除了基本的CRUD操作外,SpringBoot还提供了丰富的扩展接口,让我们能够更灵活地定制和扩展应用。以下是16个常用的SpringBoot扩展接口,掌握它们将帮助你写出更加优雅的代码。
90 0
|
2月前
|
资源调度 前端开发 JavaScript
安利一款基于canvas/svg的富文本编辑器-支持在线导出PDF、DOCX
高性能:利用Canvas和SVG进行图形和矢量图形的渲染,提供高性能的绘图能力。 可扩展性:Canvas-Editor是一个开源项目,支持通过插件机制扩展编辑器的功能,如DOCX、PDF导出、表格分页等。 丰富的文本编辑功能:支持多种文本编辑操作,如插入表格、分页、性能优化等。
279 0
|
2月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
178 1
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
115 62
下一篇
DataWorks