文章目录
  • 前言
  • 一、java 导出PDF 的几个工具
  • 1. PDF Box
  • 2. JasperReports/jFreeReport导出 报表 PDF
  • 3. itextpdf 导出PDF(敲重点)
  • 二、springboot整合itextpdf
  • 三、两个案例
  • 1. 写入HTML到PDF需要自定义工具类
  • 2. html 写入pdf 到本地
  • 3. 文本写到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。剩下的就没有太过于了解了

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

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 学习文档​


二、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>

  1. 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. spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具_html_02



  4. 内容:
  5. spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具_xml_03


四、基础知识学习

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

itextpdf 到处pdf 创建下载链接

使用itex生成pdf文件并下载总结

​itextpdf 写入 html​​​:
​ http://t.zoukankan.com/mvilplss-p-5646675.html​​