SpringBoot+Vue项目的PDF导出及给PDF文件盖章的功能示例
前言版本:SpringBoot:2.3.1.RELEASEitextpdf:5.4.3最近在做SpringBoot+Vue的项目,需要将委托单商品的数据导出为PDF文档。Java的PDF操作第三方工具类用的最多的应该是itextpdf了吧,当然以前也用过icepdf这种小众的。那现在就来看看用itextpdf怎么做,还是很简单的。首先前端页面如下,可以导出箱单和发票两种格式的PDF文件:一、引入i
·
前言
版本:
SpringBoot:2.3.1.RELEASE
itextpdf:5.4.3
最近在做SpringBoot+Vue的项目,需要将委托单商品的数据导出为PDF文档。Java的PDF操作第三方工具类用的最多的应该是itextpdf了吧,当然以前也用过icepdf这种小众的。那现在就来看看用itextpdf怎么做,还是很简单的。
首先前端页面如下,可以导出箱单和发票两种格式的PDF文件:
一、引入itextpdf依赖
<!--PDF导出-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.4.3</version>
</dependency>
只需要这一个包就可以了。网上其他教程引了一大堆包,完全没必要。
二、主要业务代码
导出发票
/**
* 导出PDF格式发票
*
* @param id
* @return io.zbus.transport.Message
* @author ZHANGCHAO
* @date 2021/1/26 13:42
**/
public Message exportCommercialInvoiceOfPdf(String id) {
Apply apply = baseMapper.selectById(id);
if (isEmpty(apply)) {
return null;
}
String tenantId = RequestKit.getRequestIn().getHeader(TENANT_ID);
Message res = new Message();
RequestKit.copyHeaders(false, TENANT_ID, HEADER_TOKEN, TENANT_TYPE);
List<ApplyInvoices> applyInvoicesList = applyInvoicesMapper.selectList(new QueryWrapper<ApplyInvoices>().lambda()
.eq(ApplyInvoices::getApplyNumber, id)
.orderByAsc(ApplyInvoices::getSequence));
apply.setApplyInvoicesList(applyInvoicesList);
// pdf文件名
String fileName = "发票_" + (isNotBlank(apply.getInvoiceNo()) ? apply.getInvoiceNo() : "无发票号") + ".pdf";
String path = ProjectPath.getExportPdfPath() + File.separator;
File file = new File(path);
if (!file.exists()) { // 如果文件夹不存在
file.mkdir(); // 创建文件夹
}
String filePath = path + fileName;
/*****************创建PDF开始*********************/
/** 实例化文档对象 */
Document document = new Document(PageSize.A4);
log.info("A4的宽度:" + PageSize.A4.getWidth() + "高度:" + PageSize.A4.getHeight());
try {
/** 创建 PdfWriter 对象 */// 文档对象的引用
// 为document创建一个监听,并把PDF流写到文件中
PdfWriter.getInstance(document, new FileOutputStream(filePath)); // 文件的输出路径+文件的实际名称
document.open();// 打开文档
// // 解决中文不显示问题
// BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
// // 设置字体大小
// Font fontChina18_BOLD = new Font(bfChinese, 18, Font.BOLD);
// Font fontChina12 = new Font(bfChinese, 12);
// Font fontChina12_BOLD = new Font(bfChinese, 12, Font.BOLD);
// Font fontChina8 = new Font(bfChinese, 8);//加粗 Font.BOLD
// Font fontChina8_BOLD = new Font(bfChinese, 8, Font.BOLD); // 加粗 Font.BOLD
//英文下字体
// Font fontContent = new Font(Font.FontFamily.HELVETICA, 18, Font.BOLD|Font.ITALIC);
// 用自己的字体
BaseFont bf = BaseFont.createFont(ProjectPath.getFontPath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
Font titleFont = new Font(bf, 20, Font.BOLDITALIC); // 24号加粗斜体
// 空格代码
Paragraph blank = new Paragraph(" ");
/**** 向文档添加内容 ***/
// 标题
String title = "";
String kehuAddress = "";
String kehuTelFax = "";
// 境外收发货人抬头信息
if (isNotBlank(apply.getConsignee())) {
Customer customer = orderService.getCustomerByName(apply.getConsignee().trim(), tenantId, isNotEmpty(apply.getConsignorId()) ? apply.getConsignorId().toString() : null);
if (isNotEmpty(customer) && isNotEmpty(customer.getCustomerAddressList())) {
title = getHeaderInfo(customer.getCustomerAddressList());
CustomerAddress ca = getAddress(customer.getCustomerAddressList());
if (isNotEmpty(ca)) {
kehuAddress = ca.getAddress();
kehuTelFax = "TEL:" + ca.getPhone() + " FAX:" + ca.getFax();
}
}
}
Paragraph titleParagraph = new Paragraph(title, titleFont);
document.add(titleParagraph); // 文档标题
document.add(blank);
Paragraph addressParagraph = new Paragraph(kehuAddress, new Font(bf, 15, Font.NORMAL));
Paragraph telFaxParagraph = new Paragraph(kehuTelFax, new Font(bf, 15, Font.NORMAL));
document.add(addressParagraph); // 客户地址
document.add(telFaxParagraph); // 客户电话+传真
document.add(blank);
document.add(blank);
document.add(blank);
// 画横线
//1.线宽度
//2.直线长度,是个百分百,0-100之间
//3.直线颜色
//4.直线位置
//5.上下移动位置
LineSeparator line = new LineSeparator(2f, 100, BaseColor.BLACK, Element.ALIGN_CENTER, 0f);
document.add(line); // 画横线
Paragraph invoiceParagraph = new Paragraph("INVOICE", new Font(bf, 20, Font.BOLD));
invoiceParagraph.setSpacingBefore(20);
document.add(invoiceParagraph); // invoice
document.add(blank);
Paragraph billTo = new Paragraph("Bill To", new Font(bf, 12, Font.BOLD));
document.add(billTo); // billto
// 承运商委托单位企业信息
String headerInfo = "";
String address = "";
String telFax = "";
if (isNotBlank(apply.getConsignor())) {
Customer customer = orderService.getCustomerByName(apply.getConsignor().trim(), tenantId, isNotEmpty(apply.getConsignorId()) ? apply.getConsignorId().toString() : null);
if (isNotEmpty(customer) && isNotEmpty(customer.getCustomerAddressList())) {
headerInfo = getHeaderInfo(customer.getCustomerAddressList());
CustomerAddress ca = getAddress(customer.getCustomerAddressList());
if (isNotEmpty(ca)) {
address = ca.getAddress();
telFax = "Tel:" + ca.getPhone() + " Fax:" + ca.getFax();
}
}
}
Paragraph headerInfoParagraph = new Paragraph(headerInfo, new Font(bf, 12, Font.NORMAL));
headerInfoParagraph.setIndentationRight(PageSize.A4.getWidth() / 2 - 30);
Paragraph addressParagraph_ = new Paragraph(address, new Font(bf, 12, Font.NORMAL));
Paragraph telFaxParagraph_ = new Paragraph(telFax, new Font(bf, 12, Font.NORMAL));
document.add(headerInfoParagraph);
document.add(addressParagraph_);
document.add(telFaxParagraph_);
// 2021/2/1 13:57@ZHANGCHAO 追加/变更/完善:获取签名地址!!
// if (isNotBlank(apply.getConsignor())) {
// Customer customer = orderService.getCustomerByName(apply.getConsignor().trim(), tenantId, isNotEmpty(apply.getConsignorId()) ? apply.getConsignorId().toString() : null);
// if (isNotEmpty(customer) && isNotEmpty(customer.getAttachmentList())) {
// // 获取已绑定的表单图片!
// List<Attachment> attachments = customer.getAttachmentList().stream()
// .filter(attachment -> "0".equals(attachment.getSubType())
// && "1".equals(attachment.getStatus())).collect(Collectors.toList());
// if (isNotEmpty(attachments)) {
// Image yinzhang = Image.getInstance(ProjectPath.getImgPath() + attachments.get(0).getPath());
// yinzhang.setAlignment(Image.ALIGN_UNDEFINED);
yinzhang.scalePercent(75); // 依照比例缩放
Image类方法:
// yinzhang.scaleAbsolute(120, 120); // 将图像缩放到绝对宽度和绝对高度。
scaleAbsoluteHeight(float newHeight); // 将图像缩放到绝对高度。
scaleAbsoluteWidth(float newWidth); //将图像缩放到绝对宽度。
scalePercent(float percent); // 将图像缩放到一定百分比。
scalePercent(float percentX, float percentY); //将图像的宽度和高度缩放到一定百分比。
scaleToFit(float fitWidth, float fitHeight); //缩放图像,使其适合特定的宽度和高度。
yinzhang.scaleToFit(120, 120); // 依照比例缩放
// yinzhang.setSpacingBefore(200);
// yinzhang.setIndentationRight(150);
// document.add(yinzhang);
// }
// }
// }
document.add(blank);
// 2021/2/1 14:38@ZHANGCHAO 追加/变更/完善:获取供应商的签名章!!
// 境外收发货人抬头信息
if (isNotBlank(apply.getConsignee())) {
Customer customer = orderService.getCustomerByName(apply.getConsignee().trim(), tenantId, isNotEmpty(apply.getConsignorId()) ? apply.getConsignorId().toString() : null);
if (isNotEmpty(customer) && isNotEmpty(customer.getAttachmentList())) {
// 获取已绑定的表单图片!
List<Attachment> attachments = customer.getAttachmentList().stream()
.filter(attachment -> "0".equals(attachment.getSubType())
&& "1".equals(attachment.getStatus())).collect(Collectors.toList());
if (isNotEmpty(attachments)) {
Image sign = Image.getInstance(ProjectPath.getImgPath() + attachments.get(0).getPath());
sign.setAlignment(Image.ALIGN_RIGHT);
// sign.scalePercent(75); // 依照比例缩放
sign.scaleToFit(120, 120); // 依照比例缩放
sign.setIndentationRight(50);
document.add(sign);
}
}
}
document.add(blank);
LineSeparator line1 = new LineSeparator(1f, 100, BaseColor.BLACK, Element.ALIGN_CENTER, 0f);
document.add(line1); // 画横线
Paragraph pg = new Paragraph("TERMS OF DELIVERY", new Font(bf, 13, Font.NORMAL));
document.add(pg);
// 转化成交方式
String transMode = "";
if (isNotBlank(apply.getTransMode())) {
DictQuery dictQuery = baseMapper.getDictInfo("CJFS", apply.getTransMode());
if (isNotEmpty(dictQuery)) {
transMode = dictQuery.getText();
}
}
Paragraph transModePG = new Paragraph(transMode, new Font(bf, 13, Font.NORMAL));
transModePG.setIndentationLeft(80);
document.add(transModePG);
Paragraph pg1 = new Paragraph("THIS PROFORMA INVOICE IS NOT ASSIGNABLE OR NEGOTIABLE", new Font(bf, 13, Font.ITALIC));
document.add(pg1);
Paragraph pg2 = new Paragraph("SUBJECT TO DELIVERY WHEN AVAILABLE AND AT PRICE IN EFFECT AT DATE OF SHIPMENT.", new Font(bf, 13, Font.ITALIC));
document.add(pg2);
// 处理表格
if (isNotEmpty(applyInvoicesList)) {
List<String> invoiceList = createInvoiceList(applyInvoicesList);
float[] columnWidths = {1.2f, // 件号
1.5f, // 英文品名
1f, // 数量
0.8f, // 单位
1.1f, // 币制
1.1f, // 单价
1.5f, // 总价
}; // 设置表格列宽参数
getCiTableList(document, 7, columnWidths, invoiceList, applyInvoicesList, "CI", 100,
new Font(bf, 13, Font.BOLD), new Font(bf, 13, Font.NORMAL));
}
// 关闭文档
document.close();
/*****************创建PDF结束*********************/
// 2021/2/8 10:53@ZHANGCHAO 追加/变更/完善:设置印章!!
boolean flag = false;
String targetPath = "";
if (isNotBlank(apply.getConsignor())) {
Customer customer = orderService.getCustomerByName(apply.getConsignor().trim(), tenantId, isNotEmpty(apply.getConsignorId()) ? apply.getConsignorId().toString() : null);
if (isNotEmpty(customer) && isNotEmpty(customer.getAttachmentList())) {
// 获取已绑定的表单图片!
List<Attachment> attachments = customer.getAttachmentList().stream()
.filter(attachment -> "0".equals(attachment.getSubType())
&& "1".equals(attachment.getStatus())).collect(Collectors.toList());
if (isNotEmpty(attachments)) {
// 读取模板文件
targetPath = path + "1-" + fileName;
InputStream input = new FileInputStream(filePath);
PdfReader reader = new PdfReader(input);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(targetPath));
// 获取操作的页面
PdfContentByte under = stamper.getOverContent(1);
Image image = Image.getInstance(ProjectPath.getImgPath() + attachments.get(0).getPath());
// 根据域的大小缩放图片
image.scaleToFit(120, 120);
// 添加图片
// 获取关键字的坐标
List<float[]> positions = PDFUtil.findKeywordPostions(new FileInputStream(filePath), "Bill To");
System.out.println("total:" + positions.size());
if (isNotEmpty(positions)) {
for (float[] position : positions) {
System.out.print("pageNum: " + (int) position[0]);
System.out.print("\tx: " + position[1]);
System.out.println("\ty: " + position[2]);
}
}
// image.setAbsolutePosition(PageSize.A4.getWidth() / 3 - 95, PageSize.A4.getHeight() / 2 + 60);
image.setAbsolutePosition(positions.get(0)[1] + 70, positions.get(0)[2] - 120);
under.addImage(image);
stamper.close();
reader.close();
flag = true;
}
}
}
String contentType = "application/octet-stream";
res.setHeader(Http.CONTENT_TYPE, contentType);
res.setStatus(RspCode.SUCCESS);
// 将文件转为字节流输出
if (flag) {
res.setBody(fileConvertToByteArray(new File(targetPath)));
// 删除文件
FileUtil.deleteFile(filePath);
FileUtil.deleteFile(targetPath);
} else {
res.setBody(fileConvertToByteArray(new File(filePath)));
// 删除文件
FileUtil.deleteFile(filePath);
}
return res;
} catch (Exception e) {
e.printStackTrace();
ExceptionUtil.getFullStackTrace(e);
}
return null;
}
导出箱单
/**
* 导出PDF格式箱单
*
* @param id
* @return io.zbus.transport.Message
* @author ZHANGCHAO
* @date 2021/1/26 13:43
**/
public Message exportPackingListOfPdf(String id) {
Apply apply = baseMapper.selectById(id);
if (isEmpty(apply)) {
return null;
}
String tenantId = RequestKit.getRequestIn().getHeader(TENANT_ID);
Message res = new Message();
RequestKit.copyHeaders(false, TENANT_ID, HEADER_TOKEN, TENANT_TYPE);
List<ApplyInvoices> applyInvoicesList = applyInvoicesMapper.selectList(new QueryWrapper<ApplyInvoices>().lambda()
.eq(ApplyInvoices::getApplyNumber, id)
.orderByAsc(ApplyInvoices::getSequence));
apply.setApplyInvoicesList(applyInvoicesList);
// pdf文件名
String fileName = "箱单_" + (isNotBlank(apply.getInvoiceNo()) ? apply.getInvoiceNo() : "无发票号") + ".pdf";
String path = ProjectPath.getExportPdfPath() + File.separator;
File file = new File(path);
if (!file.exists()) { // 如果文件夹不存在
file.mkdir(); // 创建文件夹
}
String filePath = path + fileName;
/*****************创建PDF开始*********************/
/** 实例化文档对象 */
Document document = new Document(PageSize.A4);
log.info("A4的宽度:" + PageSize.A4.getWidth() + "高度:" + PageSize.A4.getHeight());
try {
/** 创建 PdfWriter 对象 */// 文档对象的引用
// 为document创建一个监听,并把PDF流写到文件中
PdfWriter.getInstance(document, new FileOutputStream(filePath)); // 文件的输出路径+文件的实际名称
document.open();// 打开文档
// 用自己的字体
BaseFont bf = BaseFont.createFont(ProjectPath.getFontPath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
Font titleFont = new Font(bf, 20, Font.BOLDITALIC); // 24号加粗斜体
// 空格代码
Paragraph blank = new Paragraph(" ");
/**** 向文档添加内容 ***/
// 标题
String title = "";
String kehuAddress = "";
String kehuTelFax = "";
// 境外收发货人抬头信息
if (isNotBlank(apply.getConsignee())) {
Customer customer = orderService.getCustomerByName(apply.getConsignee().trim(), tenantId, isNotEmpty(apply.getConsignorId()) ? apply.getConsignorId().toString() : null);
if (isNotEmpty(customer) && isNotEmpty(customer.getCustomerAddressList())) {
title = getHeaderInfo(customer.getCustomerAddressList());
CustomerAddress ca = getAddress(customer.getCustomerAddressList());
if (isNotEmpty(ca)) {
kehuAddress = ca.getAddress();
kehuTelFax = "TEL:" + ca.getPhone() + " FAX:" + ca.getFax();
}
}
}
Paragraph titleParagraph = new Paragraph(title, titleFont);
document.add(titleParagraph); // 文档标题
document.add(blank);
Paragraph addressParagraph = new Paragraph(kehuAddress, new Font(bf, 15, Font.NORMAL));
Paragraph telFaxParagraph = new Paragraph(kehuTelFax, new Font(bf, 15, Font.NORMAL));
document.add(addressParagraph); // 客户地址
document.add(telFaxParagraph); // 客户电话+传真
document.add(blank);
document.add(blank);
Paragraph invoiceParagraph = new Paragraph("Packing list", new Font(bf, 20, Font.BOLD));
invoiceParagraph.setSpacingBefore(20);
document.add(invoiceParagraph); // invoice
document.add(blank);
// 2021/2/1 13:57@ZHANGCHAO 追加/变更/完善:获取签名地址!!
// if (isNotBlank(apply.getConsignor())) {
// Customer customer = orderService.getCustomerByName(apply.getConsignor().trim(), tenantId, isNotEmpty(apply.getConsignorId()) ? apply.getConsignorId().toString() : null);
// if (isNotEmpty(customer) && isNotEmpty(customer.getAttachmentList())) {
// // 获取已绑定的表单图片!
// List<Attachment> attachments = customer.getAttachmentList().stream()
// .filter(attachment -> "0".equals(attachment.getSubType())
// && "1".equals(attachment.getStatus())).collect(Collectors.toList());
// if (isNotEmpty(attachments)) {
// Image yinzhang = Image.getInstance(ProjectPath.getImgPath() + attachments.get(0).getPath());
// yinzhang.setAlignment(Image.ALIGN_UNDEFINED);
// yinzhang.scalePercent(75); // 依照比例缩放
// yinzhang.setIndentationRight(150);
// document.add(yinzhang);
// }
// }
// }
Paragraph billTo = new Paragraph("Bill To", new Font(bf, 12, Font.BOLD));
document.add(billTo); // billto
// 承运商委托单位企业信息
String headerInfo = "";
String address = "";
String telFax = "";
if (isNotBlank(apply.getConsignor())) {
Customer customer = orderService.getCustomerByName(apply.getConsignor().trim(), tenantId, isNotEmpty(apply.getConsignorId()) ? apply.getConsignorId().toString() : null);
if (isNotEmpty(customer) && isNotEmpty(customer.getCustomerAddressList())) {
headerInfo = getHeaderInfo(customer.getCustomerAddressList());
CustomerAddress ca = getAddress(customer.getCustomerAddressList());
if (isNotEmpty(ca)) {
address = ca.getAddress();
telFax = "Tel:" + ca.getPhone() + " Fax:" + ca.getFax();
}
}
}
Paragraph headerInfoParagraph = new Paragraph(headerInfo, new Font(bf, 12, Font.NORMAL));
headerInfoParagraph.setIndentationRight(PageSize.A4.getWidth() / 2 - 30);
Paragraph addressParagraph_ = new Paragraph(address, new Font(bf, 12, Font.NORMAL));
Paragraph telFaxParagraph_ = new Paragraph(telFax, new Font(bf, 12, Font.NORMAL));
document.add(headerInfoParagraph);
document.add(addressParagraph_);
document.add(telFaxParagraph_);
document.add(blank);
// 2021/2/1 14:38@ZHANGCHAO 追加/变更/完善:获取供应商的签名章!!
// 境外收发货人抬头信息
if (isNotBlank(apply.getConsignee())) {
Customer customer = orderService.getCustomerByName(apply.getConsignee().trim(), tenantId, isNotEmpty(apply.getConsignorId()) ? apply.getConsignorId().toString() : null);
if (isNotEmpty(customer) && isNotEmpty(customer.getAttachmentList())) {
// 获取已绑定的表单图片!
List<Attachment> attachments = customer.getAttachmentList().stream()
.filter(attachment -> "0".equals(attachment.getSubType())
&& "1".equals(attachment.getStatus())).collect(Collectors.toList());
if (isNotEmpty(attachments)) {
Image sign = Image.getInstance(ProjectPath.getImgPath() + attachments.get(0).getPath());
sign.setAlignment(Image.ALIGN_RIGHT);
// sign.scalePercent(75); // 依照比例缩放
sign.scaleToFit(120, 120); // 依照比例缩放
sign.setIndentationRight(50);
document.add(sign);
}
}
}
document.add(blank);
// 处理表格
if (isNotEmpty(applyInvoicesList)) {
PdfPTable table = new PdfPTable(6);// 设置列数
table.setSpacingBefore(20);
table.setWidthPercentage(100);// 表格宽度为100%
float[] columnWidths = {1.5f, // 件号
1.5f, // 英文品名
1.1f, // 数量
1.2f, // 净重
1.3f, // 毛重
1.3f, // 包装数
}; // 设置表格列宽参数
table.setWidths(columnWidths);
/*表头*/
getPlTableList(table, apply, new Font(bf, 13, Font.BOLD), new Font(bf, 13, Font.NORMAL));
document.add(table);
document.add(blank);
}
String lastStr = "";
String packStr = "";
if (isNotBlank(apply.getPacksKinds())) {
DictQuery dictQuery = baseMapper.getDictInfo("BZZL", apply.getPacksKinds());
if (isNotEmpty(dictQuery)) {
packStr = dictQuery.getTable();
}
}
lastStr = "TOTAL ON " + apply.getPacks() + " " + (isNotBlank(packStr) ? packStr : "");
Paragraph last = new Paragraph(lastStr, new Font(bf, 12, Font.BOLD));
document.add(last); // billto
// 关闭文档
document.close();
/*****************创建PDF结束*********************/
// 2021/2/8 10:54@ZHANGCHAO 追加/变更/完善:设置印章!!
boolean flag = false;
String targetPath = "";
if (isNotBlank(apply.getConsignor())) {
Customer customer = orderService.getCustomerByName(apply.getConsignor().trim(), tenantId, isNotEmpty(apply.getConsignorId()) ? apply.getConsignorId().toString() : null);
if (isNotEmpty(customer) && isNotEmpty(customer.getAttachmentList())) {
// 获取已绑定的表单图片!
List<Attachment> attachments = customer.getAttachmentList().stream()
.filter(attachment -> "0".equals(attachment.getSubType())
&& "1".equals(attachment.getStatus())).collect(Collectors.toList());
if (isNotEmpty(attachments)) {
// 读取模板文件
targetPath = path + "1-" + fileName;
InputStream input = new FileInputStream(filePath);
PdfReader reader = new PdfReader(input);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(targetPath));
// 获取操作的页面
PdfContentByte under = stamper.getOverContent(1);
Image image = Image.getInstance(ProjectPath.getImgPath() + attachments.get(0).getPath());
// 根据域的大小缩放图片
image.scaleToFit(120, 120);
// 添加图片
// 获取关键字的坐标
List<float[]> positions = PDFUtil.findKeywordPostions(new FileInputStream(filePath), "Bill To");
System.out.println("total:" + positions.size());
if (isNotEmpty(positions)) {
for (float[] position : positions) {
System.out.print("pageNum: " + (int) position[0]);
System.out.print("\tx: " + position[1]);
System.out.println("\ty: " + position[2]);
}
}
// image.setAbsolutePosition(PageSize.A4.getWidth() / 3 - 95, PageSize.A4.getHeight() / 2 + 60);
image.setAbsolutePosition(positions.get(0)[1] + 70, positions.get(0)[2] - 120);
under.addImage(image);
stamper.close();
reader.close();
flag = true;
}
}
}
String contentType = "application/octet-stream";
res.setHeader(Http.CONTENT_TYPE, contentType);
res.setStatus(RspCode.SUCCESS);
// 将文件转为字节流输出
if (flag) {
res.setBody(fileConvertToByteArray(new File(targetPath)));
// 删除文件
FileUtil.deleteFile(filePath);
FileUtil.deleteFile(targetPath);
} else {
res.setBody(fileConvertToByteArray(new File(filePath)));
// 删除文件
FileUtil.deleteFile(filePath);
}
return res;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
其他一些方法:
/**
* 把一个文件转化为byte字节数组。
*
* @return
*/
private byte[] fileConvertToByteArray(File file) {
byte[] data = null;
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int len;
byte[] buffer = new byte[1024];
while ((len = fis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
data = bos.toByteArray();
fis.close();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
/**
* 按一定规则获取客户抬头信息
* <p>
* 委托单导出箱单发票,获取标签为1 的地址联系人。(如果找不到取0通用地址,如果没有则取默认地址,如果没有默认取第一条)
*
* @param customerAddressList
* @return java.lang.String
* @author ZHANGCHAO
* @date 2021/1/19 9:33
**/
private String getHeaderInfo(List<CustomerAddress> customerAddressList) {
String headerInfo;
// 1.取对应
List<CustomerAddress> duiyings = customerAddressList.stream()
.filter(customerAddress -> "1".equals(customerAddress.getType())).collect(Collectors.toList());
if (isNotEmpty(duiyings)) {
headerInfo = duiyings.get(0).getHeaderInfo();
} else {
// 2.取通用
List<CustomerAddress> tongyongs = customerAddressList.stream()
.filter(customerAddress -> "0".equals(customerAddress.getType())).collect(Collectors.toList());
if (isNotEmpty(tongyongs)) {
headerInfo = tongyongs.get(0).getHeaderInfo();
} else {
// 3.取默认
List<CustomerAddress> morens = customerAddressList.stream()
.filter(CustomerAddress::getIsDefault).collect(Collectors.toList());
if (isNotEmpty(morens)) {
headerInfo = morens.get(0).getHeaderInfo();
} else {
// 4.取第一条
headerInfo = customerAddressList.get(0).getHeaderInfo();
}
}
}
return headerInfo;
}
/**
* 按一定规则获取客户地址信息
* <p>
* 委托单导出箱单发票,获取标签为1 的地址联系人。(如果找不到取0通用地址,如果没有则取默认地址,如果没有默认取第一条)
*
* @param customerAddressList
* @return java.lang.String
* @author ZHANGCHAO
* @date 2021/1/19 9:33
**/
private CustomerAddress getAddress(List<CustomerAddress> customerAddressList) {
CustomerAddress ca;
// 1.取对应
List<CustomerAddress> duiyings = customerAddressList.stream()
.filter(customerAddress -> "1".equals(customerAddress.getType())).collect(Collectors.toList());
if (isNotEmpty(duiyings)) {
ca = duiyings.get(0);
} else {
// 2.取通用
List<CustomerAddress> tongyongs = customerAddressList.stream()
.filter(customerAddress -> "0".equals(customerAddress.getType())).collect(Collectors.toList());
if (isNotEmpty(tongyongs)) {
ca = tongyongs.get(0);
} else {
// 3.取默认
List<CustomerAddress> morens = customerAddressList.stream()
.filter(CustomerAddress::getIsDefault).collect(Collectors.toList());
if (isNotEmpty(morens)) {
ca = morens.get(0);
} else {
// 4.取第一条
ca = customerAddressList.get(0);
}
}
}
return ca;
}
主要思路是先根据委托单的流水号,查询出其下的商品数据,然后写入生成的PDF文件中。再读取生成的PDF文件,根据关键字“Bill To”的坐标插入印章,最后转为字节流输出给前端下载。
1. 处理商品数据的createInvoiceList
方法:
/**
* 处理商品数据
*
* @param applyInvoicesList
* @return java.util.List<java.lang.String>
* @author ZHANGCHAO
* @date 2021/1/27 15:28
**/
public static List<String> createInvoiceList(List<ApplyInvoices> applyInvoicesList) {
List<String> invoiceList = new ArrayList<>();
/****标题行****/
invoiceList.add("Part No.");
invoiceList.add("DESCRIPTION");
invoiceList.add("QTY.");
invoiceList.add("UNIT");
invoiceList.add("CURRENCY");
invoiceList.add("Unit price");
invoiceList.add("AMOUNT");
/****每行的值****/
applyInvoicesList.forEach(applyInvoices -> {
invoiceList.add(isNotBlank(applyInvoices.getPn()) ? applyInvoices.getPn() : null); // 件号物料号
invoiceList.add(isNotBlank(applyInvoices.getEnName()) ? applyInvoices.getEnName() : null); // 英文品名
invoiceList.add(isNotEmpty(applyInvoices.getQty()) ? applyInvoices.getQty().toString() : null); // 数量
invoiceList.add(isNotBlank(applyInvoices.getQunit()) ? applyInvoices.getQunit() : null); // 单位
invoiceList.add(isNotBlank(applyInvoices.getCurrency()) ? applyInvoices.getCurrency() : null); // 币制
invoiceList.add(isNotEmpty(applyInvoices.getDcluprcamt()) ? applyInvoices.getDcluprcamt().toString() : null); // 单价
invoiceList.add(isNotEmpty(applyInvoices.getValue()) ? applyInvoices.getValue().toString() : null); // 总价
});
return invoiceList;
}
2. 获取表格数据getCiTableList
方法代码:
/**
* 创建表格
*
* @param document
* @param colspan
* @param columnWidths
* @param list
* @param widthPercentage
* @param headFont
* @param childFont
* @return void
* @author ZHANGCHAO
* @date 2021/1/27 15:44
**/
public static void getCiTableList(Document document, int colspan, float[] columnWidths, List<String> list,
List<ApplyInvoices> applyInvoices, String type,
float widthPercentage, Font headFont, Font childFont) throws DocumentException {
PdfPTable table = new PdfPTable(colspan);// 设置列数
table.setSpacingBefore(20);
table.setWidthPercentage(widthPercentage);// 表格宽度为100%
if (columnWidths != null) {//自定义列宽
table.setWidths(columnWidths);
}
int number = 0;
//设置打印行数
for (int i = 0; i < list.size() / colspan; i++) {//打印条数 = 数据个数除以列数
//每行每列生成一个单元格
for (int j = 0; j < colspan; j++) { //打印列数
PdfPCell cell = new PdfPCell(); //创建单元格
cell.setMinimumHeight(30F);//表格高度
cell.setUseAscender(true);
cell.setHorizontalAlignment(Element.ALIGN_CENTER); //水平居中
cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //垂直居中
if (i == 0) {//第一行标题栏
cell.setPhrase(new Paragraph(list.get(number), headFont));
} else {
cell.setPhrase(new Paragraph(list.get(number), childFont));
}
table.addCell(cell);
number++;
}
}
// 处理最后一行
if ("CI".equalsIgnoreCase(type)) {
BigDecimal totalQty = new BigDecimal("0");
BigDecimal totalAmount = new BigDecimal("0");
for (ApplyInvoices a : applyInvoices) {
totalQty = totalQty.add(isNotEmpty(a.getQty()) ? a.getQty() : new BigDecimal("0"));
totalAmount = totalAmount.add(isNotEmpty(a.getValue()) ? a.getValue() : new BigDecimal("0"));
}
PdfPCell cell = new PdfPCell(); //创建单元格
cell.setMinimumHeight(30F);//表格高度
cell.setColspan(2);
cell.setUseAscender(true); //开启单元格内文字位置设计
cell.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cell.setPhrase(new Paragraph("TOTAL", headFont));
table.addCell(cell);
PdfPCell cell1 = new PdfPCell(); //创建单元格
cell1.setMinimumHeight(30F);//表格高度
cell1.setUseAscender(true); //开启单元格内文字位置设计
cell1.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cell1.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cell1.setPhrase(new Paragraph(totalQty.toString(), headFont));
table.addCell(cell1);
PdfPCell cell2 = new PdfPCell(); //创建单元格
cell2.setMinimumHeight(30F);//表格高度
cell2.setUseAscender(true); //开启单元格内文字位置设计
cell2.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cell2.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cell2.setPhrase(new Paragraph("", headFont));
table.addCell(cell2);
PdfPCell cell3 = new PdfPCell(); //创建单元格
cell3.setMinimumHeight(30F);//表格高度
cell3.setUseAscender(true); //开启单元格内文字位置设计
cell3.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cell3.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cell3.setPhrase(new Paragraph("", headFont));
table.addCell(cell3);
PdfPCell cell4 = new PdfPCell(); //创建单元格
cell4.setMinimumHeight(30F);//表格高度
cell4.setUseAscender(true); //开启单元格内文字位置设计
cell4.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cell4.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cell4.setPhrase(new Paragraph("", headFont));
table.addCell(cell4);
PdfPCell cell5 = new PdfPCell(); //创建单元格
cell5.setMinimumHeight(30F);//表格高度
cell5.setUseAscender(true); //开启单元格内文字位置设计
cell5.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cell5.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cell5.setPhrase(new Paragraph(totalAmount.toString(), headFont));
table.addCell(cell5);
}
document.add(table);
}
3. 注意:箱单的话需要纵向合并单元格,而itextpdf的纵向合并简直是残废,这里需要单独处理下:
/**
* 创建箱单表格
*
* @param table
* @param apply
* @param headFont
* @param childFont
* @return void
* @author ZHANGCHAO
* @date 2021/1/28 10:53
**/
public static void getPlTableList(PdfPTable table, Apply apply, Font headFont, Font childFont) {
PdfPCell cell = new PdfPCell(); //创建单元格
cell.setMinimumHeight(30F);//表格高度
cell.setUseAscender(true); //开启单元格内文字位置设计
cell.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cell.setPhrase(new Paragraph("Part No.", headFont));
table.addCell(cell);
PdfPCell cell1 = new PdfPCell(); //创建单元格
cell1.setMinimumHeight(30F);//表格高度
cell1.setUseAscender(true); //开启单元格内文字位置设计
cell1.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cell1.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cell1.setPhrase(new Paragraph("DESCRIPTION", headFont));
table.addCell(cell1);
PdfPCell cell2 = new PdfPCell(); //创建单元格
cell2.setMinimumHeight(30F);//表格高度
cell2.setUseAscender(true); //开启单元格内文字位置设计
cell2.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cell2.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cell2.setPhrase(new Paragraph("QTY.", headFont));
table.addCell(cell2);
PdfPCell cell3 = new PdfPCell(); //创建单元格
cell3.setMinimumHeight(30F);//表格高度
cell3.setUseAscender(true); //开启单元格内文字位置设计
cell3.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cell3.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cell3.setPhrase(new Paragraph("N.WT(Kg)", headFont));
table.addCell(cell3);
PdfPCell cell4 = new PdfPCell(); //创建单元格
cell4.setMinimumHeight(30F);//表格高度
cell4.setUseAscender(true); //开启单元格内文字位置设计
cell4.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cell4.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cell4.setPhrase(new Paragraph("G.WT(Kg)", headFont));
table.addCell(cell4);
PdfPCell cell5 = new PdfPCell(); //创建单元格
cell5.setMinimumHeight(30F);//表格高度
cell5.setUseAscender(true); //开启单元格内文字位置设计
cell5.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cell5.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cell5.setPhrase(new Paragraph("Package", headFont));
table.addCell(cell5);
/****每行的值****/
List<String> invoiceList = new ArrayList<>();
apply.getApplyInvoicesList().forEach(applyInvoices -> {
invoiceList.add(isNotBlank(applyInvoices.getPn()) ? applyInvoices.getPn() : null); // 件号物料号
invoiceList.add(isNotBlank(applyInvoices.getEnName()) ? applyInvoices.getEnName() : null); // 英文品名
invoiceList.add(isNotEmpty(applyInvoices.getQty()) ? applyInvoices.getQty().toString() : null); // 数量
invoiceList.add(isNotEmpty(applyInvoices.getWeight()) ? applyInvoices.getWeight().toString() : null); // 净重
invoiceList.add(isNotEmpty(apply.getGrosswt()) ? apply.getGrosswt().toString() : null); // 毛重
invoiceList.add(isNotEmpty(apply.getPacks()) ? apply.getPacks().toString() + " CASES" : null); // 总价
});
log.info("invoiceList==> " + invoiceList);
int line = 0;
for (int i = 0; i < invoiceList.size() / 6; i++) {
for (int j = 0; j < 6; j++) {
PdfPCell cell_ = new PdfPCell(); //创建单元格
cell_.setMinimumHeight(30F);//表格高度
cell_.setUseAscender(true);
cell_.setHorizontalAlignment(Element.ALIGN_CENTER); //水平居中
cell_.setVerticalAlignment(Element.ALIGN_MIDDLE); //垂直居中
if (i == 0) {
if (j == 4 || j == 5) {
cell_.setRowspan(apply.getApplyInvoicesList().size());
String value = invoiceList.get(line);
cell_.setPhrase(new Paragraph(value, childFont));
table.addCell(cell_);
}
}
if (j != 4 && j != 5) {
cell_.setPhrase(new Paragraph(invoiceList.get(line), childFont));
table.addCell(cell_);
}
line++;
}
}
// 处理最后一行
BigDecimal totalQty = new BigDecimal("0");
BigDecimal totalWeight = new BigDecimal("0");
for (ApplyInvoices a : apply.getApplyInvoicesList()) {
totalQty = totalQty.add(isNotEmpty(a.getQty()) ? a.getQty() : new BigDecimal("0"));
totalWeight = totalWeight.add(isNotEmpty(a.getWeight()) ? a.getWeight() : new BigDecimal("0"));
}
PdfPCell cellLast = new PdfPCell(); //创建单元格
cellLast.setMinimumHeight(30F);//表格高度
cellLast.setColspan(2);
cellLast.setUseAscender(true); //开启单元格内文字位置设计
cellLast.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cellLast.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cellLast.setPhrase(new Paragraph("TOTAL", headFont));
table.addCell(cellLast);
PdfPCell cellLast1 = new PdfPCell(); //创建单元格
cellLast1.setMinimumHeight(30F);//表格高度
cellLast1.setUseAscender(true); //开启单元格内文字位置设计
cellLast1.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cellLast1.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cellLast1.setPhrase(new Paragraph(totalQty.toString(), headFont));
table.addCell(cellLast1);
PdfPCell cellLast2 = new PdfPCell(); //创建单元格
cellLast2.setMinimumHeight(30F);//表格高度
cellLast2.setUseAscender(true); //开启单元格内文字位置设计
cellLast2.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cellLast2.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cellLast2.setPhrase(new Paragraph(totalWeight.toString(), headFont));
table.addCell(cellLast2);
PdfPCell cellLast3 = new PdfPCell(); //创建单元格
cellLast3.setMinimumHeight(30F);//表格高度
cellLast3.setUseAscender(true); //开启单元格内文字位置设计
cellLast3.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cellLast3.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cellLast3.setPhrase(new Paragraph(isNotEmpty(apply.getGrosswt()) ? apply.getGrosswt().toString() : "", headFont));
table.addCell(cellLast3);
PdfPCell cellLast4 = new PdfPCell(); //创建单元格
cellLast4.setMinimumHeight(30F);//表格高度
cellLast4.setUseAscender(true); //开启单元格内文字位置设计
cellLast4.setHorizontalAlignment(Element.ALIGN_CENTER); //设置单元格的水平居中
cellLast4.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置单元格的垂直居中
cellLast4.setPhrase(new Paragraph(isNotEmpty(apply.getPacks()) ? apply.getPacks().toString() + " CASES" : null, headFont));
table.addCell(cellLast4);
}
三、测试
1. 导出的发票如下:
2. 导出的箱单如下:
总的来说用itextpdf导出PDF还是很简单的,需要其他功能可以自己研究。
以上!
更多推荐
已为社区贡献3条内容
所有评论(0)