需求背景
在工作中经常会有生成pdf文件的需求,大多数情况下,我们只需要使用pdf模版添加表单域,就足以胜任了。但是有一些特殊的需求,需要生成较为复杂的文件,如动态数据表格、插入图像等。
这时候,我们就可以使用拼接的方式,将pdf文件内容一段段拼上去,组合成一个pdf文件,来灵活的操纵文件的排版与内存形式。
itext 的使用
依赖
<dependency>
<groupid>com.itextpdf</groupid>
<artifactid>itextpdf</artifactid>
<version>5.5.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
<dependency>
<groupid>com.itextpdf</groupid>
<artifactid>itext-asian</artifactid>
<version>5.2.0</version>
</dependency>简单示例
生成一个内容为“hello world”的pdf文件
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.pdfwriter;
import java.io.filenotfoundexception;
import java.io.fileoutputstream;
import java.util.logging.level;
import java.util.logging.logger;
/**
* 生成一个内容为“hello world”的pdf文件
* @author ym
*/
public class helloworld {
public static void main(string[] args) {
string file_dir = "./"; // 项目根目录:盘符:/.../.../项目名称,注意:点号并不表示当前类文件所在的目录,而是项目目录下
//step 1—create a document.
document document = new document();
try {
//step 2—get a pdfwriter instance.
pdfwriter.getinstance(document, new fileoutputstream(file_dir + "createsamplepdf.pdf"));
//step 3—open the document.
document.open();
//step 4—add content.
document.add(new paragraph("hello world"));
//step 5—close the document.
document.close();
} catch (documentexception ex) {
logger.getlogger(helloworld.class.getname()).log(level.severe, null, ex);
} catch (filenotfoundexception ex) {
logger.getlogger(helloworld.class.getname()).log(level.severe, null, ex);
}
}
}
基础设置(页面大小、边距、字体等)
//页面大小
rectangle rect = new rectangle(pagesize.a4.rotate());
//页面背景色
rect.setbackgroundcolor(basecolor.orange);
// page , 外边距 marginleft marginright margintop marginbottom
document doc = new document(rect,90, 90, 30, 40);
// 新开一页
doc.newpage();
/**
* 段落设置
*/
paragraph titleparagraph = new paragraph("hello world!", getchinesetitlefont());
titleparagraph.setalignment(element.align_center);// 居中
titleparagraph.setfirstlineindent(24);// 首行缩进
titleparagraph.setleading(35f);// 行间距
titleparagraph.setspacingbefore(5f);// 设置上空白
titleparagraph.setspacingafter(10f);// 设置段落下空白
//支持中文 设置字体,字体颜色、大小等
public font getchinesetitlefont() throws runtimeexception {
font chinesefont = null;
try {
/**
* name – the name of the font or its location on file
* encoding – the encoding to be applied to this font
* embedded – true if the font is to be embedded in the pdf
*/
basefont simpchinese = basefont.createfont("stsongstd-light", "unigb-ucs2-h", basefont.not_embedded);
chinesefont = new font(simpchinese, 15, font.bold, basecolor.black);
} catch (documentexception e) {
log.error("getchinesefont" ,"字体异常",e);
throw new runtimeexception("getchinesefont字体异常",e);
} catch (ioexception e) {
log.error("getchinesefont" ,"字体异常",e);
throw new runtimeexception("getchinesefont字体异常",e);
}
return chinesefont;
}段落内部,特殊设置关键字 字体或颜色
// 文本内容
string content = "this is a sample text with different colors.";
string[] words = content.split(" "); // 将文本拆分为单词
for (string word : words) {
chunk chunk = new chunk(word); // 创建一个新的 chunk
// 如果单词是 "different",则设置为红色
if (word.equals("different")) {
chunk.setforegroundcolor(basecolor.red);
}
// 如果单词是 "colors.",则设置为蓝色
if (word.equals("colors.")) {
chunk.setforegroundcolor(basecolor.blue);
}
contentparagraph.add(chunk); // 将 chunk 添加到段落中
contentparagraph.add(" "); // 添加单词之间的空格
}
document.add(contentparagraph); // 将段落添加到文档中生成动态表格
// 创建一个包含5列的表格
pdfptable table = new pdfptable(5);
// 添加表头
table.addcell("header 1");
table.addcell("header 2");
table.addcell("header 3");
table.addcell("header 4");
table.addcell("header 5");
// 添加动态数据到表格
for (int i = 0; i < 10; i++) {
table.addcell("data " + i + ", 1");
table.addcell("data " + i + ", 2");
table.addcell("data " + i + ", 3");
table.addcell("data " + i + ", 4");
table.addcell("data " + i + ", 5");
}
document.add(table);
/**
* 如果需要更精细的控制属性
*/
cell = new pdfpcell(new phrase("title1",fontchinese));
cell.setcolspan(1);//设置所占列数
cell.setrowspan(1);//合并行
cell.sethorizontalalignment(element.align_center);//设置水平居中
cell.setverticalalignment(element.align_middle);//设置垂直居中
cell.setfixedheight(30);//设置高度
table.addcell(cell);页脚展示页数
pdfwriter writer = pdfwriter.getinstance(document, new fileoutputstream(file_dir + "createsamplepdf.pdf"));
writer.setpageevent(new footerevent());
public class footerevent extends pdfpageeventhelper {
//总页数
pdftemplate totalpage;
//字体
font font;
{
try {
basefont chinese = basefont.createfont("stsong-light", "unigb-ucs2-h", basefont.not_embedded);
font = new font(chinese,10);
} catch (documentexception | ioexception e) {
e.printstacktrace();
}
}
//打开文档时,创建一个总页数的模版
@override
public void onopendocument(pdfwriter writer, document document) {
pdfcontentbyte cb = writer.getdirectcontent();
totalpage = cb.createtemplate(50, 9);
}
@override
public void onendpage(pdfwriter writer, document document) {
//创建一个两列的表格
pdfptable table = new pdfptable(2);
try {
table.settotalwidth(pagesize.a4.getwidth());//总宽度为a4纸张宽度
table.setlockedwidth(true);//锁定列宽
table.setwidths(new int[]{50, 50});//设置每列宽度
pdfpcell cell = new pdfpcell(new phrase("第"+document.getpagenumber() + " 页,共", font));
cell.sethorizontalalignment(element.align_right);//设置水平右对齐
cell.setverticalalignment(element.align_middle);//设置垂直居中
cell.disableborderside(15);//隐藏全部边框
table.addcell(cell);
pdfpcell cell1 = new pdfpcell(image.getinstance(totalpage));//共 页
cell1.sethorizontalalignment(element.align_left);//设置水平左对齐
cell1.setverticalalignment(element.align_middle);//设置垂直居中
cell1.disableborderside(15);//隐藏全部边框
table.addcell(cell1);
table.writeselectedrows(0, -1, 0, 30, writer.getdirectcontent());
} catch (exception e) {
throw new exceptionconverter(e);
}
}
@override
public void onclosedocument(pdfwriter writer, document document) {
string text = "" +string.valueof(writer.getpagenumber()) +"页";
columntext.showtextaligned(totalpage, element.align_middle, new paragraph(text, font), 0, 0, 0);
}
}其他
设置密码
pdfwriter writer = pdfwriter.getinstance(doc, out);
// 设置密码为:"world"
writer.setencryption("hello".getbytes(), "world".getbytes(),
pdfwriter.allow_screenreaders,
pdfwriter.standard_encryption_128);
doc.open();
doc.add(new paragraph("hello world"));
添加水印(背景图)
//图片水印
pdfreader reader = new pdfreader(file_dir + "setwatermark.pdf");
pdfstamper stamp = new pdfstamper(reader, new fileoutputstream(file_dir
+ "setwatermark2.pdf"));
image img = image.getinstance("resource/watermark.jpg");
img.setabsoluteposition(200, 400);
pdfcontentbyte under = stamp.getundercontent(1);
under.addimage(img);
//文字水印
pdfcontentbyte over = stamp.getovercontent(2);
over.begintext();
basefont bf = basefont.createfont(basefont.helvetica, basefont.winansi,
basefont.embedded);
over.setfontandsize(bf, 18);
over.settextmatrix(30, 30);
over.showtextaligned(element.align_left, "duplicate", 230, 430, 45);
over.endtext();
//背景图
image img2 = image.getinstance("resource/test.jpg");
img2.setabsoluteposition(0, 0);
pdfcontentbyte under2 = stamp.getundercontent(3);
under2.addimage(img2);
stamp.close();
reader.close();
目录
// code 1
document.add(new chunk("chapter 1").setlocaldestination("1"));
document.newpage();
document.add(new chunk("chapter 2").setlocaldestination("2"));
document.add(new paragraph(new chunk("sub 2.1").setlocaldestination("2.1")));
document.add(new paragraph(new chunk("sub 2.2").setlocaldestination("2.2")));
document.newpage();
document.add(new chunk("chapter 3").setlocaldestination("3"));
// code 2
pdfcontentbyte cb = writer.getdirectcontent();
pdfoutline root = cb.getrootoutline();
// code 3
@suppresswarnings("unused")
pdfoutline oline1 = new pdfoutline(root, pdfaction.gotolocalpage("1", false), "chapter 1");
pdfoutline oline2 = new pdfoutline(root, pdfaction.gotolocalpage("2", false), "chapter 2");
oline2.setopen(false);
@suppresswarnings("unused")
pdfoutline oline2_1 = new pdfoutline(oline2, pdfaction.gotolocalpage("2.1", false), "sub 2.1");
@suppresswarnings("unused")
pdfoutline oline2_2 = new pdfoutline(oline2, pdfaction.gotolocalpage("2.2", false), "sub 2.2");
@suppresswarnings("unused")
pdfoutline oline3 = new pdfoutline(root, pdfaction.gotolocalpage("3", false), "chapter 3");

header, footer
pdfwriter writer = pdfwriter.getinstance(doc, new fileoutputstream(file_dir + "setheaderfooter.pdf"));
writer.setpageevent(new pdfpageeventhelper() {
public void onendpage(pdfwriter writer, document document) {
pdfcontentbyte cb = writer.getdirectcontent();
cb.savestate();
cb.begintext();
basefont bf = null;
try {
bf = basefont.createfont(basefont.helvetica, basefont.winansi, basefont.embedded);
} catch (exception e) {
e.printstacktrace();
}
cb.setfontandsize(bf, 10);
//header
float x = document.top(-20);
//左
cb.showtextaligned(pdfcontentbyte.align_left,
"h-left",
document.left(), x, 0);
//中
cb.showtextaligned(pdfcontentbyte.align_center,
writer.getpagenumber()+ " page",
(document.right() + document.left())/2,
x, 0);
//右
cb.showtextaligned(pdfcontentbyte.align_right,
"h-right",
document.right(), x, 0);
//footer
float y = document.bottom(-20);
//左
cb.showtextaligned(pdfcontentbyte.align_left,
"f-left",
document.left(), y, 0);
//中
cb.showtextaligned(pdfcontentbyte.align_center,
writer.getpagenumber()+" page",
(document.right() + document.left())/2,
y, 0);
//右
cb.showtextaligned(pdfcontentbyte.align_right,
"f-right",
document.right(), y, 0);
cb.endtext();
cb.restorestate();
}
});
doc.open();
doc.add(new paragraph("1 page"));
doc.newpage();
doc.add(new paragraph("2 page"));
doc.newpage();
doc.add(new paragraph("3 page"));
doc.newpage();
doc.add(new paragraph("4 page"));
分割 pdf
fileoutputstream out = new fileoutputstream(file_dir + "splitpdf.pdf");
document document = new document();
pdfwriter.getinstance(document, out);
document.open();
document.add(new paragraph("1 page"));
document.newpage();
document.add(new paragraph("2 page"));
document.newpage();
document.add(new paragraph("3 page"));
document.newpage();
document.add(new paragraph("4 page"));
document.close();
pdfreader reader = new pdfreader(file_dir + "splitpdf.pdf");
document dd = new document();
pdfwriter writer = pdfwriter.getinstance(dd, new fileoutputstream(file_dir + "splitpdf1.pdf"));
dd.open();
pdfcontentbyte cb = writer.getdirectcontent();
dd.newpage();
cb.addtemplate(writer.getimportedpage(reader, 1), 0, 0);
dd.newpage();
cb.addtemplate(writer.getimportedpage(reader, 2), 0, 0);
dd.close();
writer.close();
document dd2 = new document();
pdfwriter writer2 = pdfwriter.getinstance(dd2, new fileoutputstream(file_dir + "splitpdf2.pdf"));
dd2.open();
pdfcontentbyte cb2 = writer2.getdirectcontent();
dd2.newpage();
cb2.addtemplate(writer2.getimportedpage(reader, 3), 0, 0);
dd2.newpage();
cb2.addtemplate(writer2.getimportedpage(reader, 4), 0, 0);
dd2.close();
writer2.close();
合并 pdf
pdfreader reader1 = new pdfreader(file_dir + "splitpdf1.pdf");
pdfreader reader2 = new pdfreader(file_dir + "splitpdf2.pdf");
fileoutputstream out = new fileoutputstream(file_dir + "mergepdf.pdf");
document document = new document();
pdfwriter writer = pdfwriter.getinstance(document, out);
document.open();
pdfcontentbyte cb = writer.getdirectcontent();
int totalpages = 0;
totalpages += reader1.getnumberofpages();
totalpages += reader2.getnumberofpages();
java.util.list<pdfreader> readers = new arraylist<pdfreader>();
readers.add(reader1);
readers.add(reader2);
int pageofcurrentreaderpdf = 0;
iterator<pdfreader> iteratorpdfreader = readers.iterator();
// loop through the pdf files and add to the output.
while (iteratorpdfreader.hasnext()) {
pdfreader pdfreader = iteratorpdfreader.next();
// create a new page in the target for each source page.
while (pageofcurrentreaderpdf < pdfreader.getnumberofpages()) {
document.newpage();
pageofcurrentreaderpdf++;
pdfimportedpage page = writer.getimportedpage(pdfreader, pageofcurrentreaderpdf);
cb.addtemplate(page, 0, 0);
}
pageofcurrentreaderpdf = 0;
}
out.flush();
document.close();
out.close();
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论