先上个效果图
因为做的项目涉及到数据预测,其中有大量打印业务来支撑实体店的运营,因为注重的是数据,要求简洁,清晰,所以写了个很简单也很实用的工具类。
如果需要编写样式或者插入背景,都可以查阅itex官方文档,进行扩展。
这个工具是基于 itext 写的,主要作用是生成最简洁的表格,选用的jar包版本是:
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
</dependency>
废话就不多说了,直接贴代码 PDFConstants.class
import java.awt.Color;
import java.util.List; import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable; public class PDFConstants { /**
* PDF大标题字体
*/
public static Font PDFTITLEFONT = new Font(null, 16, Font.BOLD); /**
* PDF小标题字体
*/
public static Font PDFTITLEFONT1 = new Font(null, 13, Font.NORMAL); /**
* 表格宽度百分比
*/
public static Integer WIDTHPERCENTAGE = 98; /**
* 表格标题字体
*/
public static Font TITLEFONT = new Font(null, 12, Font.COURIER); /**
* 翻页加载表头
*/
public static Integer HEADERROWS = 1; /**
* 翻页不加载表头
*/
public static Integer NOHEADERROWS = 0; /**
* 表格内容字体
*/
public static Font CONTENTFONT = new Font(null, 9, Font.NORMAL); /**
* PDF表格样式
*/
private static PdfPCell cell = new PdfPCell(); /**
* 获取表格
*/
public static PdfPCell getCell() {
// 水平居中
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
// 垂直居中
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
// 边距
cell.setPadding(1);
// 行高
cell.setMinimumHeight(22);
// 不换行
// cell.setNoWrap(true);
// 颜色淡化
cell.setBorderColor(Color.decode("#EBEEF5"));
return cell;
} /**
* 获取表格并赋值
*/
public static PdfPCell getCell(Paragraph content) {
cell = getCell();
// 设置内容
cell.setPhrase(content);
return cell;
} /**
* @Description 生成PDF表格
* @param titleNum
* 列数
* @param tableWidth
* 列宽
* @param titles
* 标题集合
* @param contents
* 内容集合
* @param headerRows
* 是否再次加载表头
* @return
* @throws Exception
*/
public static PdfPTable getPDFTable(int titleNum, int[] tableWidth, String[] titles, List<String> contents, int headerRows) throws Exception {
// 创建表格对象
// 列数
PdfPTable table = new PdfPTable(titleNum); //表格宽度百分比
table.setWidthPercentage(WIDTHPERCENTAGE); // 列宽百分比
if (tableWidth != null)
table.setWidths(tableWidth); // 翻页加载表头
if (headerRows == HEADERROWS)
table.setHeaderRows(HEADERROWS); // 标题集合
String[] pdfTitles = titles;
if (pdfTitles != null && pdfTitles.length > 0) {
// 标题
for (String pdfTitle : pdfTitles) {
PdfPCell title = getCell(new Paragraph(pdfTitle, TITLEFONT));
table.addCell(title);
}
}
// 内容集合
List<String> pdfContents = contents;
if (pdfContents != null && pdfContents.size() > 0) {
// 内容
for (String pdfContent : pdfContents) {
PdfPCell content = getCell(new Paragraph(pdfContent, CONTENTFONT));
table.addCell(content);
}
} // 撑行数,否则最后一行会消失
table.addCell("");
table.completeRow();
return table;
} }
分页工具类 PDFMaker.class
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfPageEventHelper;
import com.lowagie.text.pdf.PdfTemplate;
import com.lowagie.text.pdf.PdfWriter; /**
* @Description 分页工具
* @author ry
* @date 2019年7月12日
*/
public class PDFMaker extends PdfPageEventHelper { /** 这个PdfTemplate实例用于保存总页数 */
public PdfTemplate tpl;
/** 页码字体 */
public BaseFont helv; @Override
public void onCloseDocument(PdfWriter writer, com.lowagie.text.Document arg1) {
tpl.beginText();
tpl.setFontAndSize(helv, 12);
tpl.setTextMatrix(0, 0);
tpl.showText("" + (writer.getPageNumber() - 1));
tpl.endText();
} /*
* (non-Javadoc)
*
* @see
* com.lowagie.text.pdf.PdfPageEventHelper#onEndPage(com.lowagie.text.pdf
* .PdfWriter, com.lowagie.text.Document)
*/
@Override
public void onEndPage(PdfWriter writer, com.lowagie.text.Document document) {
PdfContentByte cb = writer.getDirectContent();
cb.saveState(); String text = " Page " + writer.getPageNumber() + " of ";
float textSize = helv.getWidthPoint(text, 9);
float textBase = document.bottom();
cb.beginText();
cb.setFontAndSize(helv, 9);
// for odd pagenumbers, show t cb.setTextMatrix(document.left(), textBase);
cb.showText(text);
cb.endText();
cb.addTemplate(tpl, document.left() + textSize, textBase);
cb.restoreState();
} /*
* (non-Javadoc)
*
* @see
* com.lowagie.text.pdf.PdfPageEventHelper#onOpenDocument(com.lowagie.text
* .pdf.PdfWriter, com.lowagie.text.Document)
*/
@Override
public void onOpenDocument(PdfWriter writer, com.lowagie.text.Document arg1) {
try {
// initialization of the template
tpl = writer.getDirectContent().createTemplate(100, 100); // tpl.setBoundingBox(new Rectangle(0, 0, 10, 10));
// initialization of the font
helv = BaseFont.createFont("Helvetica", BaseFont.WINANSI, false);
} catch (Exception e) { }
} }
注意:网上大部分此工具类都会报错,生成PDF失败 Unbalanced save/restore state operators,这是因为调用了saveState()但是没调用restoreState(),这里我已经修正了
拿出部分业务代码做例子,使用这个工具是很简单的
首先打开一个文档
// 定义文件路径 你可以完成过程后删掉这个临时文件 或者存在tmp里
File f = new File("xxxx/xxx.pdf");
FileOutputStream output = new FileOutputStream(f);
// 实例化文档对象
Document document = new Document(PageSize.A4, 0, 0, 0, 0);
// 创建 PdfWriter 对象 文件的输出路径+文件的实际名称
PdfWriter writer = PdfWriter.getInstance(document, output);
// 设置分页
writer.setPageEvent(new PDFMaker()); document.open();// 打开文档
Document有横向属性 使用方法是 PageSize.A4.rotate()这个rotate方法是个神奇的方法
后面四个数字对应的是边距 分别是 左,右,上,下
生成table几个传参的例子
// 标题
String[] title = { "Min.", "SUN", "MON", "TUE", "WED", "THUR", "FRI", "SAT" }; // 列数
Integer titleNum = 8; // 列宽
int tableWidth[] = { 15, 15, 15, 10, 10, 12, 12, 11 };
//内容
List<String> contents = new ArrayList<String>();
//TODO 业务代码填充contens // 获取PDFTable
PdfPTable table = PDFConstants.getPDFTable(titleNum, tableWidth, title, contents, 0); //表格上间距
table.setSpacingBefore(0);
//添加进文档
document.add(table);
//关闭文档
document.close();
如果大家有什么不解,或意见,欢迎在下方留言,楼主看到就会回复的,谢谢。