java实现生成pdf_详解Java生成PDF文档方法
最近项目需要实现PDF下载的功能,由于没有这方面的经验,从网上花了很长时间才找到相关的资料。整理之后,发现有如下几个框架可以实现这个功能。
1. 开源框架支持
iText,生成PDF文档,还支持将XML、Html文件转化为PDF文件;
Apache PDFBox,生成、合并PDF文档;
docx4j,生成docx、pptx、xlsx文档,支持转换为PDF格式。
比较:
iText开源协议为AGPL,而其他两个框架协议均为Apache License v2.0。
使用PDFBox生成PDF就像画图似的,文字和图像根据页面坐标画上去的,需要根据字数手动换行。
docx4j用来生成docx文档,提供了将WORD文档转换为PDF文档的功能,并不能直接生成PDF文档。
2. 实现方案
—
格式复杂
格式简单
数据量大
docx4j+freemarker
docx4j或PDFBox
数据量小
docx4j
PDFBox
2.1 纯数据生成PDF
1.docx4j,适用于生成格式简单或格式复杂且数据量小的PDF文档; 2.Apache PDFBox,适用于生成格式简单且数据量小的PDF文档。
1.docx4j
docx4j是一个开源java库,用于创建和操作Microsoft Open XML(Word docx,Powerpoint pptx和Excel xlsx)文件。它类似于Microsoft的OpenXML SDK,但适用于Java。docx4j使用JAXB来创建内存中的对象表示,程序员需要花时间了解JAXB和Open XML文件结构 。
// word对象
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
// 文档主体
MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();
// 换行符
Br br = objectFactory.createBr();
// 段落
P p = objectFactory.createP();
// 段落设置
PPr ppr = objectFactory.createPPr();
// 文字位置
Jc jc = new Jc();
jc.setVal(je);
ppr.setJc(jc);
// 行设置
RPr rpr = objectFactory.createRPr();
// 字体设置
RFonts rFonts = objectFactory.createRFonts();
rFonts.setAscii("Times New Roman");
rFonts.setEastAsia("宋体");
rpr.setRFonts(rFonts);
// 行
R r = objectFactory.createR();
// 文本
Text text = objectFactory.createText();
text.setValue("这是一段普通文本");
r.setRPr(rpr);
r.getContent().add(br);
r.getContent().add(text);
p.getContent().add(r);
p.setPPr(ppr);
// 添加到正文中
mainDocumentPart.addObjecthttp://www.cppcns.com(p);
// 导出
//..
2.Apache PDFBox Apache PDFBox是处理PDF文档的一个开源的Java工具。该项目允许创建新的PDF文档,处理现有文档以及从文档中提取内容的功能。Apache PDFBox还包括几个命令行实用程序。
String formTemplate = "/Users/xiaoming/Desktop/test_pdfbox.pdf";
// 定义文档对象
PDDocument document = new PDDocument();
// 定义一页,大小A4
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
// 获取字体
PDType0Font font = PDType0Font.load(document, new File("/Users/xiaoming/work/tmp/simsun.ttf"));
// 定义页面内容流
PDPageContentStream stream = new PDPageContentStream(document, page);
// 设置字体及文字大小
stream.setFont(font, 12);
// 设置画笔颜色
stream.setNonStrokingColor(Color.BLACK);
// 添加矩形
stream.addRect(29, 797, 100, 14);
// 填充矩形
stream.fill();
stream.setNonStrokingColor(Color.BLACK);
// 文本填充开始
stream.beginText();
// 设置行距
stream.setLeading(18f);
// 设置文字位置
stream.newLineAtOffset(30, 800);
// 填充文字
stream.showText("呵呵");
// 换行
stream.newLine();
stream.showText("哈哈");
stream.newLine();
stream.showText("嘻嘻");
// 文本填充结束
stream.endText();
// 关闭流
stream.close();
// 保存
document.save(formTemplate);
// 释放资源
document.close();
2.2 模版+数据生成PDF
FreeMarker+docx4j,适用于生成格式复杂且数据量大的PDF文档
Apache FreeMarker是一个模板引擎,用于根据模板和更改数据生成文本输出(HTML网页,电子邮件,配置文件,源代码等)。模板是用FreeMarker模板语言(FTL)编写的,是一种简单的专用语言。
Office2003以上,Word是可以以XML文本格式存储的。先将要生成的PDF转换为Word文档 ,再将其保存为XML文本,通过模版引擎将数据填充到XML文本中,最后再反向转换为PDF文档。简单来说就是PDF->Word->XML->Word->PDF的流程。
步骤
描述
工具
1
word -> xml
手动
2
xml -> ftl
手动,参考《XML格式Word文档常用标签介绍》
3
ftl + obj = xml
freemarker
4
xml -> pdf
docx4j
步骤
1 把pdf文档对应的word(docx)制作出来
2 把word文档另存为xml文件
3 将xml文件制作为freemarker模版(ftl)文件
4 将数据和ftl文件组装为xml文本
Map map = new HashMap<>();
map.put("name", "小明");
map.put("address", "北京市朝阳区");
map.put("email", "xiaoming@abc.com");
StringWriter stringWriter = new StringWriter();
BufferedWriter writer = new BufferedWriter(stringWriter);
template.process(map, writer);
String xmlStr = stringWriter.toString();
5 使用docx4j将xml文本加载为word文档对象
ByteArrayInputStream in = new ByteArrayInputStream(xmlStr.getBytes());
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(in);
6 使用docx4j将word文档转存为pdf文档
String outputfilepath = "/Users/xiaoming/简历.pdf";
FileOutputStream os = new FileOutputStream(new File(outputFilePath));
FOSettings foSettings = Docx4J.createFOSettings();
foSettings.setWmlPackage(wordMLPackage);
Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
// Docx4J.toPDF(wordMLPackage, new FileOutputStream(new File(outputfilepath)));
2.3 Word转PDF
docx4j
WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(new File("abc.docx"));
Mapper fontMapper = new IdentityPlusMapper();
// fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));
mlPackage.setFontMapper(fontMapper);
Out
2.4 合并多个PDF
Apache PDFBox,将多个PDF文档合并
String folderName = "/Users/xiaoming/pdfs";
String destP编程客栈nt compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
for (int i = 0; i < filesInFolder.length; i++) {
mergBXPoJBFyEePdf.addSource(folderName + File.separator + filesInFolder[i]);
}
mergePdf.setDestinationFileName(destPath);
mergePdf.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
示例代码
github.com/brandonbai/…
以上所述是小编给大家介绍的Java生成PDF文档方法详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
本文标题: 详解Java生成PDF文档方法
本文地址: http://www.cppcns.com/ruanjian/java/257514.html
java实现生成pdf_详解Java生成PDF文档方法相关推荐
- 详解pdfFactory转换PDF文档的预览窗口视图
不同的预览视图可以帮助用户更好地使用pdfFactory的不同功能.比如,在进行页面的添加.删除.排列时,用户可以使用缩略图视图,来更好地管理页面:而在进行文本内容的调整时,普通视图能更好地聚焦在同一 ...
- java生成pdf方法_详解Java生成PDF文档方法|chu
最近项目需要实现PDF下载的功能,由于没有这方面的经验,从网上花了很长时间才找到相关的资料.整理之后,发现有如下几个框架可以实现这个功能. 1. 开源框架支持iText,生成PDF文档,还支持将XML ...
- java内部格式_详解java内部类的访问格式和规则
详解java内部类的访问格式和规则 1.内部类的定义 定义一个类来描述事物,但是这个事物其中可能还有事物,这时候在类中再定义类来描述. 2.内部类访问规则 ①内部类可以直接访问外部类中的成员,包括私有 ...
- java 引用传递_详解java的值传递、地址传递、引用传递
详解java的值传递.地址传递.引用传递 一直来觉得对值传递和地址传递了解的很清楚,刚才在开源中国上看到一篇帖子介绍了java中的值传递和地址传递,看完后感受颇深.下边总结下以便更容易理解. 按照以前 ...
- java comparator相等_详解Java中Comparable和Comparator接口的区别
详解Java中Comparable和Comparator接口的区别 发布于 2020-7-20| 复制链接 摘记: 详解Java中Comparable和Comparator接口的区别本文要来详细分析一 ...
- java switch中if_详解java中if语句和switch的使用
if语句 说起if语句,那么不得不提起三元运算符 a>b?c=0:c=1; 如果a>b结果为true,那么c=0,为false,c=1 那么下面看下if语句 if(a>b)c=0; ...
- python java混合编程_详解java调用python的几种用法(看这篇就够了)
java调用python的几种用法如下: 在java类中直接执行python语句 在java类中直接调用本地python脚本 使用Runtime.getRuntime()执行python脚本文件(推荐 ...
- java 自动装载_java_详解Java的Spring框架下bean的自动装载方式,Spring容器可以自动装配相互协 - phpStudy...
详解Java的Spring框架下bean的自动装载方式 Spring容器可以自动装配相互协作bean之间的关系,这有助于减少对XML配置,而无需编写一个大的基于Spring应用程序的较多的和元素. 自 ...
- Java implement意思_详解JAVA中implement和extends的区别
详解JAVA中implement和extends的区别 发布于 2020-4-14| 复制链接 摘记: 详解JAVA中implement和extends的区别extends是继承父类,只要那个类不是声 ...
- java sleep唤醒_详解Java中的线程让步yield()与线程休眠sleep()方法
Java中的线程让步会让线程让出优先级,而休眠则会让线程进入阻塞状态等待被唤醒,这里我们对比线程等待的wait()方法,来详解Java中的线程让步yield()与线程休眠sleep()方法 线程让步: ...
最新文章
- vs2010中svn使用教程_SVN安装以及和VS2010整合使用-阿里云开发者社区
- MySQL 主从架构配置详解
- Xgboost简易入门教程
- 模仿Retrofit封装一个使用更简单的网络请求框架
- 声明属性Hibernate的Annotation注解
- SAP Fiori ButtonRenderer
- NET中使用Memcached的相关资源整理
- .NET Core 2.0 开源Office组件 NPOI
- 【转】温故之.NET 异步
- c语言自定义一个函数求商和余数,c – 如何在一个步骤中获得商和余数?
- mysql select带字段名_关于Select * 与Select 字段名 的问题!
- 数据库事物隔离级别用到的锁再次理解
- 初识python你应该知道的6个知识点
- 【PHP学习】—get请求传递参数(五)
- Java集合的框架和实现类
- CPU+GPU异构集群搭建的总结说明
- 软考高级 真题 2016年上半年 信息系统项目管理师 论文
- tkmybatis 枚举值处理
- 如何快速删除某几页的页眉页脚
- 天天向上答案python_天天向上的力量python(举一反三)