1、使用java textpdf 自定义生成pdf报告文件,报告元素包含:
- 封面
- 背景图片
- PDF页头
- PDF页尾
- 报告页面下标
- 文字颜色
2、java maven 引入关键jar包
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.4</version>
</dependency>
3、编写java入口
//以下dataMap 暂时没有使用
public final static void initPdf(Map<String, Object> dataMap) throws Exception {
Document document = new Document(PageSize.A4, 25, 25, 30, 55);
String path = "模板测试-" + System.currentTimeMillis() + ".pdf";
final String dir = System.getProperty("user.dir") + "/output";
File file = new File(dir);
if (!file.exists()) {
file.mkdir();
}
path = dir + File.separator + path;
FileOutputStream os = new FileOutputStream(path);
PdfWriter writer = PdfWriter.getInstance(document, os);
// 设置页面布局
writer.setViewerPreferences(PdfWriter.PageLayoutOneColumn);
// 设置页码
writer.setPageEvent(new PageNumberHelper());
document.open();
// 添加页眉和页脚
addPageHeader(document, writer);
addPageFooter(document, writer);
addCover(document,dataMap); // 添加封面
//新开一个页面
document.newPage();
document.add(ElementUtil.addMenu("1.测试菜单", baseFont));
document.add(ElementUtil.addSubTitle("1.1 测试子菜单标题", baseFont));
document.add(ElementUtil.addSubTitle(
ElementUtil.buildFragmentText("黑色", baseFont,BaseColor.BLACK),
ElementUtil.buildFragmentText("红色", baseFont,BaseColor.RED),
ElementUtil.buildFragmentText("绿色", baseFont,BaseColor.GREEN),
ElementUtil.buildFragmentText("蓝色", baseFont,BaseColor.BLUE)
));
document.add(ElementUtil.addMenu("2.测试菜单", baseFont));
document.add(ElementUtil.addMenu("3.测试菜单", baseFont));
document.add(ElementUtil.addMenu("4.测试菜单", baseFont));
document.close();
System.out.println("pdf生成成功,文件路径:" + path);
writer.close();
}
4、编写页码处理逻辑
package pdf.v1;
import com.itextpdf.text.Document;
import com.itextpdf.text.ExceptionConverter;
import com.itextpdf.text.pdf.*;
public class PageNumberHelper extends PdfPageEventHelper {
// pdf模板
public PdfTemplate pdfTemplate;
// 设置字体
public static BaseFont baseFont;
static {
try {
baseFont = BaseFont.createFont(System.getProperty("user.dir") + "/fonts/simsun.ttc,0", BaseFont.IDENTITY_H,
BaseFont.EMBEDDED);
} catch (Exception e) {
throw new ExceptionConverter(e);
}
}
/**
* 重写PdfPageEventHelper中的onOpenDocument方法
*/
@Override
public void onOpenDocument(PdfWriter writer, Document document) {
// 得到文档的内容并为该内容新建一个模板
pdfTemplate = writer.getDirectContent().createTemplate(500, 500);
}
/**
* 重写PdfPageEventHelper中的onEndPage方法
* 定位页码
*/
@Override
public void onEndPage(PdfWriter writer, Document document) {
// 新建获得用户页面文本和图片内容位置的对象
final PdfContentByte pdfContentByte = writer.getDirectContent();
// 保存图形状态
pdfContentByte.saveState();
String text = writer.getPageNumber() + "/";
// 获取点字符串的宽度
float textSize = baseFont.getWidthPoint(text, 8);
pdfContentByte.beginText();
// 设置随后的文本内容写作的字体和字号
pdfContentByte.setFontAndSize(baseFont, 8);
// 定位'X/'
float x = (document.right() + document.left())/2;
float y = 10f;
pdfContentByte.setTextMatrix(x, y);
pdfContentByte.showText(text);
pdfContentByte.endText();
// 将模板加入到内容(content)中- // 定位'Y'
pdfContentByte.addTemplate(pdfTemplate, x + textSize, y);
pdfContentByte.restoreState();
}
/**
* 重写PdfPageEventHelper中的onCloseDocument方法
*/
@Override
public void onCloseDocument(PdfWriter writer, Document document) {
pdfTemplate.beginText();
pdfTemplate.setFontAndSize(baseFont, 8);
pdfTemplate.setTextMatrix(0, 0);
// 设置总页数的值到模板上,并应用到每个界面
pdfTemplate.showText(String.valueOf(writer.getPageNumber()));
pdfTemplate.endText();
}
}
5、编写页头处理逻辑
package pdf.v1;
import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;
import java.util.List;
public class PageHeader extends PdfPageEventHelper {
private TableConfig tableConfig;
private PdfPTable headerTable;
public PageHeader(TableConfig tableConfig, PdfPTable headerTable) {
this.tableConfig = tableConfig;
this.headerTable = headerTable;
}
@Override
public void onEndPage(PdfWriter writer, Document document) {
//把页眉表格定位
headerTable.writeSelectedRows(0, -1, 0, 836, writer.getDirectContent());
}
/**
* 设置页眉
*
* @param writer
* @throws Exception
*/
public void setTableHeader(PdfWriter writer, TableConfig tableConfig)throws Exception {
headerTable = new PdfPTable(tableConfig.getNumColumns()); //创建表格
headerTable.setTotalWidth(tableConfig.getTotalWidth());
headerTable.setLockedWidth(tableConfig.isLockedWidth());
headerTable.setHorizontalAlignment(tableConfig.getHorizontalAlignment());
headerTable.setWidthPercentage(tableConfig.getWidthPercentage());
List<TableCellConfig> cellConfigs = tableConfig.getCellConfigs();
for (TableCellConfig cellConfig : cellConfigs) {
if(cellConfig.getCellType()==0) {
PdfPCell cell = new PdfPCell();
cell.disableBorderSide(cellConfig.getDisableBorderSide());
cell.setBackgroundColor(cellConfig.getBackgroundColor());
cell.setBorderColor(cellConfig.getBorderColor());
cell.setPaddingTop(cellConfig.getPadding()[0]);
cell.setPaddingRight(cellConfig.getPadding()[1]);
cell.setPaddingBottom(cellConfig.getPadding()[2]);
cell.setPaddingLeft(cellConfig.getPadding()[3]);
cell.setHorizontalAlignment(cellConfig.getHorizontalAlignment());
cell.setVerticalAlignment(cell.getVerticalAlignment());
cell.setColspan(cellConfig.getColspan());
cell.setRowspan(cellConfig.getRowspan());
Paragraph p = new Paragraph(cellConfig.getCellData(), cellConfig.getFont());
cell.addElement(p);
headerTable.addCell(cell);
}
if(cellConfig.getCellType()==1) {
PdfPCell cell = new PdfPCell();
cell.setColspan(cellConfig.getColspan());
cell.setRowspan(cellConfig.getRowspan());
cell.setBorderColor(cellConfig.getBorderColor());
cell.setHorizontalAlignment(cellConfig.getHorizontalAlignment());
Image image = Image.getInstance(cellConfig.getImgUrl());
image.scaleToFit(60,30);
cell.addElement(image);
cell.disableBorderSide(cellConfig.getDisableBorderSide());
cell.setBackgroundColor(cellConfig.getBackgroundColor());
cell.setBorderColor(cellConfig.getBorderColor());
cell.setPaddingTop(cellConfig.getPadding()[0]);
cell.setPaddingRight(cellConfig.getPadding()[1]);
cell.setPaddingBottom(cellConfig.getPadding()[2]);
cell.setPaddingLeft(cellConfig.getPadding()[3]);
cell.setHorizontalAlignment(cellConfig.getHorizontalAlignment());
cell.setVerticalAlignment(cell.getVerticalAlignment());
headerTable.addCell(cell);
}
}
PageHeader event = new PageHeader(tableConfig, headerTable);
writer.setPageEvent(event);
}
}
6、编写页尾处理逻辑
package pdf.v1;
import com.itextpdf.text.Document;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;
import java.util.List;
public class PageFooter extends PdfPageEventHelper {
private PdfPTable footer;
private TableConfig tableConfig;
@SuppressWarnings("static-access")
public PageFooter(TableConfig tableConfig, PdfPTable footer) {
this.tableConfig = tableConfig;
this.footer = footer;
}
@Override
public void onEndPage(PdfWriter writer, Document document) {
//把页脚表格定位
footer.writeSelectedRows(0, -1, 0, 30, writer.getDirectContent());
}
/**
* 页脚是文字
*
* @param writer
* @param tableConfig
*/
public void setTableFooter(PdfWriter writer, TableConfig tableConfig) {
footer = new PdfPTable(tableConfig.getNumColumns());
footer.setTotalWidth(tableConfig.getTotalWidth());
List<TableCellConfig> cellConfigs = tableConfig.getCellConfigs();
for (TableCellConfig cellConfig : cellConfigs) {
PdfPCell cell = new PdfPCell();
cell.setBorder(cellConfig.getBorder());
cell.setBorderColor(cellConfig.getBorderColor());
Paragraph p = new Paragraph(cellConfig.getCellData(), cellConfig.getFont());
cell.setPaddingTop(cellConfig.getPadding()[0]);
cell.setPaddingRight(cellConfig.getPadding()[1]);
cell.setPaddingBottom(cellConfig.getPadding()[2]);
cell.setPaddingLeft(cellConfig.getPadding()[3]);
cell.setHorizontalAlignment(cellConfig.getHorizontalAlignment());
cell.setVerticalAlignment(cell.getVerticalAlignment());
cell.addElement(p);
footer.addCell(cell);
}
PageFooter event = new PageFooter(tableConfig, footer);
writer.setPageEvent(event);
}
}