欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解Java生成PDF文档方法

程序员文章站 2024-02-24 10:10:46
最近项目需要实现pdf下载的功能,由于没有这方面的经验,从网上花了很长时间才找到相关的资料。整理之后,发现有如下几个框架可以实现这个功能。 1. 开源框架支持...

最近项目需要实现pdf下载的功能,由于没有这方面的经验,从网上花了很长时间才找到相关的资料。整理之后,发现有如下几个框架可以实现这个功能。

1. 开源框架支持

  1. itext,生成pdf文档,还支持将xml、html文件转化为pdf文件;
  2. apache pdfbox,生成、合并pdf文档;
  3. docx4j,生成docx、pptx、xlsx文档,支持转换为pdf格式。

比较:

  1. itext开源协议为agpl,而其他两个框架协议均为apache license v2.0。
  2. 使用pdfbox生成pdf就像画图似的,文字和图像根据页面坐标画上去的,需要根据字数手动换行。
  3. 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.addobject(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)制作出来

详解Java生成PDF文档方法

2 把word文档另存为xml文件

 详解Java生成PDF文档方法

3 将xml文件制作为freemarker模版(ftl)文件

详解Java生成PDF文档方法

 4 将数据和ftl文件组装为xml文本

map<string, object> 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); 
outputstream os = new java.io.fileoutputstream("abc.pdf");  
fosettings fosettings = docx4j.createfosettings(); 
fosettings.setwmlpackage(mlpackage); 
docx4j.tofo(fosettings, os, docx4j.flag_export_prefer_xsl); 

2.4 合并多个pdf

apache pdfbox,将多个pdf文档合并

string foldername = "/users/xiaoming/pdfs";
string destpath = "/users/xiaoming/all.pdf";
pdfmergerutility mergepdf = new pdfmergerutility();
string[] filesinfolder = getfiles(foldername);
arrays.sort(filesinfolder, new comparator<string>() {
   @override
   public int compare(string o1, string o2) {
     return o1.compareto(o2);
   }
});
for (int i = 0; i < filesinfolder.length; i++) {
   mergepdf.addsource(foldername + file.separator + filesinfolder[i]);
}
mergepdf.setdestinationfilename(destpath);
mergepdf.mergedocuments(memoryusagesetting.setupmainmemoryonly());

示例代码

github.com/brandonbai/…

以上所述是小编给大家介绍的java生成pdf文档方法详解整合,希望对大家有所帮助