需求:将数据库中的一些表格信息导出并存入pdf文件。于是乎接触到了itextpdf工具类,帮助我们更好的编排内容显示的位置和文件的导出。
页面的红色字体为截图工具的标准,不是代码生成的文字哦。
*如果您感觉符合您的需求,建议您在gitee下载源码,帮助您更快的实现您想要的效果。
源码地址
3.1、步骤一:引入依赖
<!-- itextPdf start -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.4.3</version>
</dependency>
<!-- end -->
3.2、步骤二:创建文本对象和文件输出地址
// 定义全局的字体静态变量
private static Font titlefont;
private static Font keyfont;
private static Font textfont;
// 静态代码块
static {
try {
// 不同字体(这里定义为同一种字体:包含不同字号、不同style)
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
titlefont = new Font(bfChinese, 16, Font.BOLD);
keyfont = new Font(bfChinese, 10, Font.BOLD);
textfont = new Font(bfChinese, 10, Font.NORMAL);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws FileNotFoundException, DocumentException {
//1、创建Document对象,页面默认为A4格式,页面边框默认为30磅
Document document = new Document(PageSize.A4);
//2、设置文件输出路径
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("D:/text.pdf"));
//3、设置pdf页眉和页脚和水印
MyHeaderFooter headerFooter = new MyHeaderFooter();
writer.setPageEvent(headerFooter);
//4、给pdf填充内容
document.open();
//4.1、第一行:填入二维码和条形码
PdfPTable header = createTable(new float[] {260, 260});
header.addCell(createQrCode());
header.addCell(createBarcode(writer));
//设置当前table距离下方table内容的间距
header.setSpacingAfter(10);
document.add(header);
//4.2、添加标题
PdfPTable title = createTable(new float[] {120, 200, 200});
title.addCell(createCell("员工列表信息", titlefont, Element.ALIGN_LEFT, 1, 3, false));
//表头
title.addCell(createCell("员工ID", keyfont, Element.ALIGN_CENTER, 1, 1, true));
title.addCell(createCell("员工名称", keyfont, Element.ALIGN_CENTER, 1, 1, true));
title.addCell(createCell("员工职称", keyfont, Element.ALIGN_CENTER, 1, 1, true));
//内容
title.addCell(createCell("1001", textfont, Element.ALIGN_CENTER, 1, 1, true));
title.addCell(createCell("张三", textfont, Element.ALIGN_CENTER, 1, 1, true));
title.addCell(createCell("初级工程师", textfont, Element.ALIGN_CENTER, 1, 1, true));
title.addCell(createCell("1002", textfont, Element.ALIGN_CENTER, 1, 1, true));
title.addCell(createCell("李四", textfont, Element.ALIGN_CENTER, 1, 1, true));
title.addCell(createCell("中级工程师", textfont, Element.ALIGN_CENTER, 1, 1, true));
title.setSpacingAfter(10);
document.add(title);
//4.3 实线分割
// 直线
Paragraph p1 = new Paragraph();
p1.add(new Chunk(new LineSeparator()));
p1.setSpacingAfter(40f);
document.add(p1);
// 虚线-分割线
Paragraph p2 = new Paragraph();
for (int i = 0; i < 71; i++) {
Chunk chunk = new Chunk("- ");
p2.add(chunk);
}
p2.setSpacingAfter(40);
document.add(p2);
//4.4、列合并 --员工职称列合并
PdfPTable colContent = createTable(new float[] {120, 200, 200});
colContent.addCell(createCell("员工列表信息", titlefont, Element.ALIGN_LEFT, 1, 3, false));
colContent.addCell(createCell("员工ID", keyfont, Element.ALIGN_CENTER, 1, 1, true));
colContent.addCell(createCell("员工名称", keyfont, Element.ALIGN_CENTER, 1, 1, true));
colContent.addCell(createCell("员工职称", keyfont, Element.ALIGN_CENTER, 1, 1, true));
//内容
colContent.addCell(createCell("1001", textfont, Element.ALIGN_CENTER, 1, 1, true));
colContent.addCell(createCell("张三", textfont, Element.ALIGN_CENTER, 1, 1, true));
colContent.addCell(createCell("初级工程师", textfont, Element.ALIGN_CENTER, 2, 1, true));
colContent.addCell(createCell("1002", textfont, Element.ALIGN_CENTER, 1, 1, true));
colContent.addCell(createCell("李四", textfont, Element.ALIGN_CENTER, 1, 1, true));
colContent.setSpacingAfter(10);
document.add(colContent);
//4.5、行合并 -员工列表信息行合并
PdfPTable rowContent = createTable(new float[] {120, 200, 200});
rowContent.addCell(createCell("员工列表信息", titlefont, Element.ALIGN_LEFT, 1, 3, true));
//表头
rowContent.addCell(createCell("员工ID", keyfont, Element.ALIGN_CENTER, 1, 1, true));
rowContent.addCell(createCell("员工名称", keyfont, Element.ALIGN_CENTER, 1, 1, true));
rowContent.addCell(createCell("员工职称", keyfont, Element.ALIGN_CENTER, 1, 1, true));
//内容
rowContent.addCell(createCell("1001", textfont, Element.ALIGN_CENTER, 1, 1, true));
rowContent.addCell(createCell("张三", textfont, Element.ALIGN_CENTER, 1, 1, true));
rowContent.addCell(createCell("初级工程师", textfont, Element.ALIGN_CENTER, 1, 1, true));
rowContent.addCell(createCell("1002", textfont, Element.ALIGN_CENTER, 1, 1, true));
rowContent.addCell(createCell("李四", textfont, Element.ALIGN_CENTER, 1, 1, true));
rowContent.addCell(createCell("中级工程师", textfont, Element.ALIGN_CENTER, 1, 1, true));
rowContent.setSpacingAfter(10);
document.add(rowContent);
//结束关闭对象
document.close();
}
3.3、步骤三:封装生成表格对象方法
/**
* 创建指定列宽、列数的表格
* @param widths 创建表单并设置初始的一行中每一个表格的长度
* @return table对象
*/
public static PdfPTable createTable(float[] widths) {
PdfPTable table = new PdfPTable(widths);
try {
// 最大宽度
int maxWidth = 520;
table.setTotalWidth(maxWidth);
table.setLockedWidth(true);
table.setHorizontalAlignment(Element.ALIGN_CENTER);
table.getDefaultCell().setBorder(1);
} catch (Exception e) {
e.printStackTrace();
}
return table;
}
3.4、步骤四:封装生成单元格对象方法
/**
* 创建单元格(指定字体、水平居..、单元格跨x列合并、设置单元格内边距)
* @param value 内容
* @param font 字体格式
* @param align 内容位置
* @param rowspan 行合并数
* @param colspan 列合并数
* @param boderFlag 边框是否显示
* @return cell对象
*/
public static PdfPCell createCell(String value, Font font, int align, int rowspan, int colspan, boolean boderFlag) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
//行列合并数
cell.setRowspan(rowspan);
cell.setColspan(colspan);
cell.setPhrase(new Phrase(value, font));
cell.setPadding(3.0f);
//是否显示边框
if (!boderFlag) {
cell.setBorder(0);
cell.setPadding(5.0f);
} else {
//设置表格内容距离变宽的位置
cell.setPadding(5.0f);
}
return cell;
}
3.5、步骤五:生成二维码
/**
* 生成二维码
*/
public static PdfPCell createQrCode(){
PdfPCell cell = new PdfPCell();
//1、绘制二维码
BarcodeQRCode code = new BarcodeQRCode("这是二维码", 500, 500, null);
try {
//生成二维码图片,并设置绝对值大小
Image image = code.getImage();
image.setAbsolutePosition(50, 50);
//2、生成二维码图像
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
//cell.setPadding(2);
cell.setImage(image);
} catch (BadElementException e) {
e.printStackTrace();
}
return cell;
}
3.6、步骤六:生成条形码
public static PdfPCell createBarcode(PdfWriter writer){
PdfPCell cell = new PdfPCell();
//1、绘制条形码
Barcode128 code = new Barcode128();
//2、字号,条码高度,条码和数字间距
code.setSize(6);
code.setBarHeight(35);
code.setBaseline(5);
//3、条形码值
code.setCode("123456789");
cell.setPadding(2);
cell.setImage(code.createImageWithBarcode(writer.getDirectContent(), null, null));
return cell;
}
3.7、步骤七:实现生成pdf页面事件监听
/**
* 继承 PdfPageEventHelper 实现生成pdf页面事件监听
* 功能一:页眉和页脚
* 功能二:页面水印设置
*/
class MyHeaderFooter extends PdfPageEventHelper{
// 总页数 -默认体制
PdfTemplate totalPage;
Font hfFont;
//static代码块优先于代码块执行
{
try {
hfFont = new Font(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 8, Font.BOLD);
} catch (DocumentException | IOException e) {
e.printStackTrace();
}
}
// 打开文档时,创建一个总页数的模版
@Override
public void onOpenDocument(PdfWriter writer, Document document) {
PdfContentByte cb =writer.getDirectContent();
totalPage = cb.createTemplate(30, 16);
}
// 一页加载完成触发,写入页眉和页脚
@Override
public void onEndPage(PdfWriter writer, Document document) {
PdfPTable table = new PdfPTable(2);
try {
//1、设置header的长度
table.setTotalWidth(PageSize.A4.getWidth() - 75);
table.setWidths(new int[] { 25, 25});
table.setLockedWidth(true);
table.getDefaultCell().setFixedHeight(-10);
// 总页数
PdfPCell totalCell = new PdfPCell(Image.getInstance(totalPage));
//去边框
totalCell.setBorder(0);
totalCell.setHorizontalAlignment(Element.ALIGN_LEFT);
// 初始页
PdfPCell cell = new PdfPCell();
//去边框
cell.setBorder(0);
cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
cell.setPhrase(new Phrase("第" + writer.getPageNumber() + "页/", hfFont));
table.addCell(cell);
table.addCell(totalCell);
// 将页眉写到document中,位置可以指定,指定到下面就是页脚
// xPost设置距离左边框距离 -页脚
table.writeSelectedRows(0, -1, 30,20, writer.getDirectContent());
//页眉
table.writeSelectedRows(0, -1, 30,PageSize.A4.getHeight() - 20, writer.getDirectContent());
//2、添加水印
generateWaterMark(writer);
} catch (Exception de) {
throw new ExceptionConverter(de);
}
}
// 全部完成后,将总页数的pdf模版写到指定位置
@Override
public void onCloseDocument(PdfWriter writer, Document document) {
String text = "总" + (writer.getPageNumber()-1) + "页";
ColumnText.showTextAligned(totalPage, Element.ALIGN_LEFT, new Paragraph(text,hfFont), 1, 6, 0);
}
/**
* 生成pdf页面添加水印
* @param writer pdf写入类
*/
private static void generateWaterMark(PdfWriter writer){
BaseFont bfChinese;
try {
bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
PdfContentByte under = writer.getDirectContentUnder();
under.beginText();
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.5f);
under.setGState(gs);
under.setLeading(0.5f);
under.setColorFill(new BaseColor(255, 170, 0));
under.setFontAndSize(bfChinese, 24);
under.setTextMatrix(300, 600);
under.showTextAligned(Element.ALIGN_CENTER, "你好,这是水印!", 300, 600, 315);
under.endText();
} catch (DocumentException | IOException e) {
e.printStackTrace();
}
}
}
谢谢您的阅览,期待对您有所帮助。