依赖基于:PDF模板填充,基于IText5-CSDN博客
工具类
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* PDF动态表格(基于itext5)
*/
public class PDFDynamicTable {
private transient final Document document;
/**
* 字体,默认:STSong-Light
*/
private BaseFont baseFont;
/**
* 表头
*/
private List<CellData[]> headers;
public static PDFDynamicTable load() throws DocumentException, IOException {
return new PDFDynamicTable();
}
/**
* 设置表格边距
*
* @param marginLR - 左右边距
* @param marginTB - 上下边距
*/
public PDFDynamicTable margin(float marginLR, float marginTB) {
marginLR = Math.max(this.document.leftMargin(), marginLR);
marginTB = Math.max(this.document.topMargin(), marginTB);
this.document.setMargins(marginLR, marginLR, marginTB, marginTB);
return this;
}
/**
* 添加表头
*/
public PDFDynamicTable headers(List<CellData[]> headers) {
if (headers == null) {
return this;
}
this.headers = headers;
return this;
}
public byte[] create(List<CellData[]> tableData) throws DocumentException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(document, out);
// 打开文档
document.open();
// 创建动态表格
document.add(doCreateDynamicTable(tableData));
document.close();
writer.close();
return out.toByteArray();
}
private PdfPTable doCreateDynamicTable(List<CellData[]> tableData) {
Rectangle rectangle = document.getPageSize();
PdfPTable table = new PdfPTable(tableData.get(0).length);
table.setExtendLastRow(false);
table.setLockedWidth(true);
float totalWidth = rectangle.getWidth() - document.leftMargin() - document.rightMargin();
table.setTotalWidth(totalWidth);
// 添加表头
if (!this.headers.isEmpty()) {
table.setHeaderRows(this.headers.size());
handleTableCellData(table, headers);
}
// 添加表体
handleTableCellData(table, tableData);
return table;
}
private void handleTableCellData(PdfPTable table, List<CellData[]> dataList) {
out:
for (CellData[] dataArray : dataList) {
for (int j = 0; j < dataArray.length; j++) {
CellData data = dataArray[j];
if (data == null) {
// 结束当前行
table.completeRow();
continue out;
}
PdfPCell cell = createPdfCell(data.value, data.fontSize, data.hAlign, data.vAlign);
// 合并列
int colspan = Math.min(dataArray.length - j, data.colspan);
cell.setColspan(colspan);
table.addCell(cell);
if (colspan == dataArray.length) {
// 结束当前行
table.completeRow();
continue out;
}
}
}
}
private PDFDynamicTable() throws DocumentException, IOException {
this.document = new Document();
this.baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
this.headers = Collections.emptyList();
}
private PdfPCell createPdfCell(String content, float fontSize, int hAlign, int vAlign) {
PdfPCell cell = new PdfPCell();
cell.setBorder(Rectangle.BOX);
cell.setBorderWidth(0.5F);
cell.setPadding(5F);
cell.setHorizontalAlignment(hAlign);
cell.setVerticalAlignment(vAlign);
cell.setPhrase(createContent(content, fontSize));
return cell;
}
private Phrase createContent(String content, float fontSize) {
Phrase phrase = new Phrase();
phrase.setFont(new Font(baseFont, fontSize));
phrase.add(content);
return phrase;
}
public static class CellData {
/**
* 标题内容
*/
private String value;
/**
* 当前单元格合并列数(默认为0,不合并)
*/
private int colspan;
/**
* 字体大小
*/
private float fontSize;
/**
* 水平对齐方式
* <p>
* 0-LEFT;
* 1-CENTER;
* 2-RIGHT
*/
private int hAlign;
/**
* 垂直对齐方式
* <p>
* 4-TOP;
* 5-MIDDLE;
* 6-BOTTOM
*/
private int vAlign;
public CellData(String value) {
this(value, 10.5F);
}
public CellData(String value, float fontSize) {
this(value, 1, fontSize);
}
public CellData(String value, int colspan, float fontSize) {
this(value, Math.max(1, colspan), fontSize, Element.ALIGN_LEFT, Element.ALIGN_MIDDLE);
}
public CellData(String value, int colspan, float fontSize, int hAlign) {
this(value, colspan, fontSize, hAlign, Element.ALIGN_MIDDLE);
}
public CellData(String value, int colspan, float fontSize, int hAlign, int vAlign) {
this.value = value;
this.colspan = Math.max(1, colspan);
this.fontSize = fontSize;
this.hAlign = Arrays.asList(0, 1, 2).contains(hAlign) ? hAlign : Element.ALIGN_LEFT;
this.vAlign = Arrays.asList(4, 5, 6).contains(vAlign) ? vAlign : Element.ALIGN_MIDDLE;
}
}
}
测试demo
public static void main(String[] args) throws DocumentException, IOException {
String dir = FileSystemView.getFileSystemView().getHomeDirectory().getPath() + "/table/";
List<PDFDynamicTable.CellData[]> headers = new ArrayList<>();
PDFDynamicTable.CellData[] head = new PDFDynamicTable.CellData[2];
head[0] = new PDFDynamicTable.CellData("测试标题数据", 2, 20F, Element.ALIGN_CENTER);
headers.add(head);
PDFDynamicTable.CellData[] head1 = new PDFDynamicTable.CellData[2];
head1[0] = new PDFDynamicTable.CellData("第一列标题");
head1[1] = new PDFDynamicTable.CellData("第二列标题");
headers.add(head1);
List<PDFDynamicTable.CellData[]> data = new ArrayList<>();
for (int i = 0; i < 10; i++) {
PDFDynamicTable.CellData[] arr = new PDFDynamicTable.CellData[2];
arr[0] = new PDFDynamicTable.CellData("row " + (i + 1) + ", col 1");
arr[1] = new PDFDynamicTable.CellData("row " + (i + 1) + ", col 2");
data.add(arr);
}
byte[] bytes = PDFDynamicTable.load()
.margin(120F, 50F)
.headers(headers)
.create(data);
IOUtils.write(bytes, Files.newOutputStream(Paths.get(dir + System.nanoTime() + ".pdf")));
}