JAVA生成行程单PDF
一、pom依赖
首先引入PDF需要的pom依赖
<!-- pdf-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
<optional>true</optional>
</dependency>
二、PDF操作工具类及行程单实体类
创建PDF操作工具类及行程单实体类,调用 PDFUtil.createPDFFile()方法创建行程单。
/**
* PDF操作工具类
*/
public class PDFUtil {
private static Logger logger = LoggerFactory.getLogger(PDFUtil.class);
public static final String PDF_FILE_SUFFIX = ".pdf";
public static Font headFont;
public static Font keyFont;
// 标题
public static Font titleFont;
// 设置字体大小
public static Font textFont;
public static final int MAX_WIDTH = 520;
static {
//中文格式
BaseFont bfChinese;
try {
// 设置中文显示
bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
headFont = new Font(bfChinese, 10, java.awt.Font.BOLD);
keyFont = new Font(bfChinese, 8, java.awt.Font.BOLD);
textFont = new Font(bfChinese, 8, Font.NORMAL);
titleFont = new Font(bfChinese, 16, Font.NORMAL);
} catch (Exception e) {
logger.error("创建pdf格式失败,异常={}", e);
throw new RuntimeException(e);
}
}
/**
* 为表格添加一个内容
*
* @param value 值
* @param font 字体
* @param align 对齐方式
* @return 添加的文本框
*/
public static PdfPCell createCell(String value, Font font, int align) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
font.setColor(BaseColor.WHITE);
cell.setPhrase(new Phrase(value, font));
cell.setBackgroundColor(BaseColor.GRAY);
return cell;
}
/**
* 为表格添加一个内容
*
* @param value 值
* @param font 字体
* @return 添加的文本框
*/
public static PdfPCell createCell(String value, Font font) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setPhrase(new Phrase(value, font));
return cell;
}
/**
* 为表格添加一个内容
*
* @param value 值
* @param font 字体
* @param align 对齐方式
* @param colspan 占多少列
* @return 添加的文本框
*/
public static PdfPCell createCell(String value, Font font, int align, int colspan) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setColspan(colspan);
cell.setPhrase(new Phrase(value, font));
return cell;
}
/**
* 为表格添加一个内容
*
* @param value 值
* @param font 字体
* @param align 对齐方式
* @param colspan 占多少列
* @param boderFlag 是否有有边框
* @return 添加的文本框
*/
public static PdfPCell createCell(String value, Font font, int align, int colspan,
boolean boderFlag) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setColspan(colspan);
cell.setPhrase(new Phrase(value, font));
cell.setPadding(3.0f);
if (!boderFlag) {
cell.setBorder(0);
cell.setPaddingTop(4.0f);
cell.setPaddingBottom(8.0f);
}
return cell;
}
/**
* 创建一个表格对象
*
* @param colNumber 表格的列数
* @return 生成的表格对象
*/
public static PdfPTable createTable(int colNumber) {
PdfPTable table = new PdfPTable(colNumber);
table.setTotalWidth(MAX_WIDTH);
table.setLockedWidth(true);
table.setHorizontalAlignment(Element.ALIGN_CENTER);
table.getDefaultCell().setBorder(1);
return table;
}
public PdfPTable createTable(float[] widths) {
PdfPTable table = new PdfPTable(widths);
try {
table.setTotalWidth(MAX_WIDTH);
table.setLockedWidth(true);
table.setHorizontalAlignment(Element.ALIGN_CENTER);
table.getDefaultCell().setBorder(1);
} catch (Exception e) {
e.printStackTrace();
}
return table;
}
public static PdfPTable createBlankTable() {
PdfPTable table = new PdfPTable(1);
table.getDefaultCell().setBorder(0);
table.addCell(createCell("", keyFont));
table.setSpacingAfter(20.0f);
table.setSpacingBefore(20.0f);
return table;
}
/**
* 提供外界调用的接口,生成以head为表头,list为数据的pdf
*
* @param fileName 文件名
* @param titleName 表单名
* @param headName 数据表头
* @param headField 对应类的属性名
* @param list 数据
*/
public static <T> File generatePDFs(String fileName, String titleName, String[] headName, String[] headField,
List<T> list) {
// 建立一个Document对象
Document document = new Document();
// 设置页面大小
document.setPageSize(PageSize.A4);
File tempFile = null;
try {
tempFile = File.createTempFile(fileName, PDF_FILE_SUFFIX);
PdfWriter.getInstance(document, new FileOutputStream(tempFile));
document.open();
} catch (Exception e) {
e.printStackTrace();
}
Class classType = list.get(0).getClass();
int colNum = headName.length;
PdfPTable table = createTable(colNum);
// 添加标题
table.addCell(createCell(titleName, titleFont, Element.ALIGN_CENTER, colNum, false));
//设置表头
for (int i = 0; i < colNum; i++) {
table.addCell(createCell(headName[i], keyFont, Element.ALIGN_CENTER));
}
for (int i = 0; i < list.size(); i++) {
T t = list.get(i);
for (int j = 0; j < colNum; j++) {
//获得get方法,getName,getAge等
String getMethodName = "get" + headField[j].substring(0, 1).toUpperCase() + headField[j].substring(1);
try {
//通过反射获得相应的get方法,用于获得相应的属性值
Method method = classType.getMethod(getMethodName, new Class[]{});
logger.debug(getMethodName + ":" + method.invoke(t, new Class[]{}) + ",");
//添加数据
table.addCell(createCell(method.invoke(t, new Class[]{}).toString(), textFont));
} catch (Exception e) {
logger.error("属性设值错误:入参={},异常={}", JSON.toJSONString(t), e);
throw new RuntimeException(e);
}
}
}
try {
//将表格添加到文档中
document.add(table);
} catch (Exception e) {
logger.error("");
throw new RuntimeException(e);
}
//关闭流
document.close();
return tempFile;
}
/**
* 构建行程单PDF文件
* @param date 构建日期
* @param phone 手机号
* @param baseTripInfos 行程信息
* @param outputStream 输出流
*/
public static void createPDFFile(Date date, String phone, List<BaseTripInfo> baseTripInfos, OutputStream outputStream) {
String[] header = new String[]{"序号", "出站时间", "入站站点", "出站站点", "金额(元)"};
int[] width = new int[]{20, 45, 35, 35, 35};
Document document = null;
try {
// 建立一个Document对象
document = new Document();
// 设置页面大小
document.setPageSize(PageSize.A4);
PdfWriter.getInstance(document, outputStream);
document.open();
// 设置列以及列宽度
PdfPTable table = PDFUtil.createTable(header.length);
table.setWidths(width);
// 添加标题以及空行
table.addCell(PDFUtil.createCell("广州地铁—行程单", PDFUtil.titleFont, Element.ALIGN_CENTER, header.length, false));
table.addCell(PDFUtil.createCell(" ", PDFUtil.titleFont, Element.ALIGN_CENTER, header.length, false));
// 设置申请日期以及行程起止日期
table.addCell(PDFUtil.createCell("申请时间:" + cn.hutool.core.date.DateUtil.format(date, "yyyy-MM-dd"), PDFUtil.textFont, Element.ALIGN_LEFT, 2, false));
table.addCell(PDFUtil.createCell("行程人手机号:" + phone, PDFUtil.textFont, Element.ALIGN_LEFT, 2, false));
// 计算该行程单总金额
double totalAmount = 0;
for (BaseTripInfo baseTripInfo : baseTripInfos) {
totalAmount += Double.parseDouble(baseTripInfo.getPrice());
}
table.addCell(PDFUtil.createCell("共" + baseTripInfos.size() + "笔行程, 合计 " + NumberUtil.round(totalAmount, 2).toString() + "元",
PDFUtil.textFont, Element.ALIGN_LEFT, header.length, false));
// 设置表头
for (String headName : header) {
table.addCell(PDFUtil.createCell(headName, PDFUtil.keyFont, Element.ALIGN_CENTER));
}
for (int i = 0; i < baseTripInfos.size(); i++) {
// 序号
table.addCell(createTextCell(String.valueOf(i + 1)));
// 出站时间
table.addCell(createTextCell(baseTripInfos.get(i).getExitDate() == null ? "" :
baseTripInfos.get(i).getExitDate()));
// 进站站点
table.addCell(createTextCell(baseTripInfos.get(i).getEnterStation() == null ? "" :
baseTripInfos.get(i).getEnterStation()));
// 出站站点
table.addCell(createTextCell(baseTripInfos.get(i).getExitStation() == null ? "" :
baseTripInfos.get(i).getExitStation()));
// 扣费金额
double price = Double.parseDouble(baseTripInfos.get(i).getPrice());
table.addCell(createTextCell(NumberUtil.round(price, 2).toString()));
}
//将表格添加到文档中
document.add(table);
} catch (DocumentException e) {
logger.error("Document添加PdfWriter实例失败", e);
} finally {
//关闭流
if (document != null) {
document.close();
}
}
}
private static PdfPCell createTextCell(String value) {
return PDFUtil.createCell(value, PDFUtil.textFont);
}
}
/**
* 行程单信息
*/
public class BaseTripInfo {
/**
* 行程ID
*/
private String tripId;
/**
* 入站站点
*/
private String enterStation;
/**
* 入站时间
*/
private String enterDate;
/**
* 出站站点
*/
private String exitStation;
/**
* 出站时间
*/
private String exitDate;
/**
* 金额
*/
private String price;
/**
* 设备ID
*/
private String deviceId;
public String getTripId() {
return tripId;
}
public void setTripId(String tripId) {
this.tripId = tripId;
}
public String getEnterStation() {
return enterStation;
}
public void setEnterStation(String enterStation) {
this.enterStation = enterStation;
}
public String getEnterDate() {
return enterDate;
}
public void setEnterDate(String enterDate) {
this.enterDate = enterDate;
}
public String getExitStation() {
return exitStation;
}
public void setExitStation(String exitStation) {
this.exitStation = exitStation;
}
public String getExitDate() {
return exitDate;
}
public void setExitDate(String exitDate) {
this.exitDate = exitDate;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
@Override
public String toString() {
return "BaseTripInfo{" +
"tripId='" + tripId + '\'' +
", enterStation='" + enterStation + '\'' +
", enterDate='" + enterDate + '\'' +
", exitStation='" + exitStation + '\'' +
", exitDate='" + exitDate + '\'' +
", price='" + price + '\'' +
", deviceId='" + deviceId + '\'' +
'}';
}
}