java根据模板生成pdf文件并导出
这几天做账单功能客户要求做出一个将页面导出pdf文件,方便统计。
主要实现思路:
1.调试pdf模板
2.将数据塞进模板里面
3.下载pdf文件到本地
进过网上查找,发现iText可以实现这个功能,首先找到一个PdfUtil,可以在本地调试样式
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import java.util.Map;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
public class PdfUtil {
private String path;//保存路径
private String pdfName; //padf名字
private boolean isShowReturnMoney;//是否有返利
public PdfUtil() {
}
public PdfUtil(String path,String pdfName,boolean isShowReturnMoney) {
this.path=path;
this.pdfName=pdfName;
this.isShowReturnMoney=isShowReturnMoney;
}
//setPdf方法主要将参数塞进pdf模板 里面的参数可以自由配置
public void setPdf(List<Map<String, Object>> list,List<Map<String, Object>> list1,String memberCkeckTime,String title,String realName,String beforemoney,String overmoney,String totalordermoney,String totalmoney,String img,String photoimg) {
//创建文件
Document document = new Document(PageSize.A4);
PdfWriter writer = null;
try {
File dir = new File(path);
if (dir.exists()) {
dir.mkdirs();
}
//创建一个书写器
writer = PdfWriter.getInstance(document, new FileOutputStream(path + pdfName));
//打开文件
document.open();
//中文字体,解决中文不能显示问题
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
//黑字体
Font titleFont = new Font(bfChinese);
titleFont.setColor(BaseColor.BLACK);
titleFont.setSize(18);
titleFont.setStyle(Font.BOLD);//
//段落文本
Paragraph paragraphBlue = new Paragraph(title, titleFont);
paragraphBlue.setAlignment(Element.ALIGN_CENTER);//居中
document.add(paragraphBlue);
Font font2 = new Font(bfChinese);
font2.setSize(16);
font2.setStyle(Font.BOLD);
Paragraph paragraph2 = new Paragraph("账户信息", font2);
document.add(paragraph2);
//生成表格
PdfPTable table = new PdfPTable(2);
table.setHorizontalAlignment(Element.ALIGN_CENTER);
table.getDefaultCell().setBorder(0);//设置表格为无边框
table.setSpacingBefore(16);
table.setSpacingAfter(10);
table.setWidthPercentage(80);
Font font3 = new Font(bfChinese);
font3.setSize(14);
Paragraph paragraph3 = new Paragraph("客户名称:" + realName, font3);
PdfPCell cell = new PdfPCell(paragraph3);
cell.setVerticalAlignment(Element.ALIGN_CENTER);// 垂直居中
cell.setColspan(2);// 跨2行
cell.setBorder(0);
PdfPCell cell4 = new PdfPCell(new Paragraph("上期结余:" + beforemoney, font3));
cell4.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
cell4.setBorder(0);
cell4.setMinimumHeight(40);
PdfPCell cell5 = new PdfPCell(new Paragraph("本期欠款:" + overmoney, font3));
cell5.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
cell5.setBorder(0);
cell5.setMinimumHeight(40);
Paragraph cell6 = new Paragraph("本期发货:" + totalordermoney, font3);
Paragraph cell7 = new Paragraph("本期回款:" + totalmoney, font3);
table.addCell(cell);
table.addCell(cell4);
table.addCell(cell5);
table.addCell(cell6);
table.addCell(cell7);
document.add(table);
//客户销售明细
if (list != null && list.size() > 0) {
Paragraph paragraph4 = new Paragraph("客户销售明细", font2);
document.add(paragraph4);
PdfPTable table2 = new PdfPTable(15);
table2.setHorizontalAlignment(Element.ALIGN_CENTER);
table2.getDefaultCell().setBorder(0);//设置表格为无边框
table2.setSpacingBefore(15);
table2.setSpacingAfter(10);
table2.setWidthPercentage(96);
Font font4Title = new Font(bfChinese);
font4Title.setSize(12);
font4Title.setStyle(Font.BOLD);
Font font4 = new Font(bfChinese);
font4.setSize(12);
addPDFTable1(table2, font4Title, "日期", "产品", "数量", "价格", "金额", "类型", "交货单号");
for (int i = 0; i < list.size(); i++) {
String deliveryTime = list.get(i).get("deliveryTime").toString();
deliveryTime = deliveryTime.substring(0,10);
addPDFTable1(table2, font4,deliveryTime,(String)list.get(i).get("productName"),list.get(i).get("quantityModify").toString(),list.get(i).get("price").toString(),list.get(i).get("amount").toString(),(String)list.get(i).get("note"),(String)list.get(i).get("erpOrderId"));
// System.out.println((String)list.get(i).get("note"));
// System.out.println(list.get(i).get("amount").toString());
// System.out.println(list.get(i).get("deliveryTime").toString());
// System.out.println(list.get(i).get("price").toString());
// System.out.println((String)list.get(i).get("erpOrderId"));
// System.out.println(list.get(i).get("quantityModify").toString());
// System.out.println((String)list.get(i).get("productName"));
// quantityModify += Integer.valueOf(list.get(i).get("quantityModify").toString()) ;
}
document.add(table2);
}
//账户明细
if (list1 != null && list1.size() > 0) {
Paragraph paragraph4 = new Paragraph("账户明细", font2);
document.add(paragraph4);
PdfPTable table2 = null;
String s4 = null;
if (isShowReturnMoney) {//是否需要显示返利
table2 = new PdfPTable(6);
s4 = "返利";
} else {
table2 = new PdfPTable(5);
}
table2.setHorizontalAlignment(Element.ALIGN_CENTER);
table2.getDefaultCell().setBorder(0);//设置表格为无边框
table2.setSpacingBefore(15);
table2.setSpacingAfter(10);
table2.setWidthPercentage(96);
Font font4Title = new Font(bfChinese);
font4Title.setSize(12);
font4Title.setStyle(Font.BOLD);
Font font4 = new Font(bfChinese);
font4.setSize(12);
addPDFTable2(table2, font4Title, "日期", "发货", "回款", s4, "摘要");
for (int i = 0; i < list1.size(); i++) {
String s = null;
if (isShowReturnMoney) {
s = "返利";
}
String addDateTime = list1.get(i).get("addDateTime").toString();
addDateTime = addDateTime.substring(0,10);
addPDFTable2(table2, font4, addDateTime,totalordermoney,list1.get(i).get("money").toString(),s,(String)list1.get(i).get("note"));
}
document.add(table2);
}
//确认信息
Paragraph paragraph4 = new Paragraph("确认信息", font2);
document.add(paragraph4);
PdfPTable table2 = new PdfPTable(2);
table2.setHorizontalAlignment(Element.ALIGN_CENTER);
table2.getDefaultCell().setBorder(0);//设置表格为无边框
table2.setSpacingBefore(15);
table2.setSpacingAfter(10);
table2.setWidthPercentage(96);
Font font4Title = new Font(bfChinese);
font4Title.setSize(12);
font4Title.setStyle(Font.BOLD);
Font font4 = new Font(bfChinese);
font4.setSize(12);
PdfPCell c1 = new PdfPCell(new Paragraph("在场证明:", font3));
c1.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
c1.setHorizontalAlignment(Element.ALIGN_LEFT);//水平居中
c1.setBorder(0);
c1.setMinimumHeight(28);
PdfPCell c2 = new PdfPCell(new Paragraph("客户签名:", font3));
c2.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
c2.setHorizontalAlignment(Element.ALIGN_LEFT);//水平居中
c2.setBorder(0);
c2.setMinimumHeight(28);
table2.addCell(c1);
table2.addCell(c2);
//拍照
//图片可以是网络地址 可以是本地图片 调试的时候讲 photoimg改成常量就可以了
PdfPCell c3 = new PdfPCell();
if(img != "") {
Image image = Image.getInstance(photoimg);//图片地址
image.scaleAbsoluteWidth(108);
c3.setHorizontalAlignment(Element.ALIGN_LEFT);
c3.addElement(image);
c3.setBorder(0);
c3.setPaddingLeft(10);
table2.addCell(c3);
}
//签名
if (photoimg != "") {
PdfPCell c4 = new PdfPCell();
c4.setHorizontalAlignment(Element.ALIGN_LEFT);
Image image2 = Image.getInstance(img);
image2.scaleAbsoluteWidth(168);
c4.setPaddingLeft(10);
c4.addElement(image2);
c4.setBorder(0);
table2.addCell(c4);
}
PdfPCell cellTime = new PdfPCell(new Paragraph("确认时间:" + memberCkeckTime, font4));
cellTime.setBorder(0);
cellTime.setHorizontalAlignment(Element.ALIGN_RIGHT);
cellTime.setVerticalAlignment(Element.ALIGN_CENTER);
cellTime.setMinimumHeight(36);
cellTime.setColspan(2);
cell.setPaddingTop(20);
table2.addCell(cellTime);
document.add(table2);
document.close();
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
void addPDFTable1(PdfPTable table, Font font3, String s1, String s2, String s3, String s4, String s5, String s6, String s7) {
//添加表头
PdfPCell c1 = new PdfPCell(new Paragraph(s1, font3));
c1.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
c1.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
c1.setColspan(2);// 跨2行
c1.setBorder(0);
c1.setMinimumHeight(28);
PdfPCell c2 = new PdfPCell(new Paragraph(s2, font3));
c2.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
c2.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
c2.setColspan(4);// 跨2列
c2.setBorder(0);
c2.setMinimumHeight(28);
PdfPCell c3 = new PdfPCell(new Paragraph(s3, font3));
c3.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
c3.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
c3.setColspan(3);// 跨2列
c3.setBorder(0);
c3.setMinimumHeight(28);
PdfPCell c4 = new PdfPCell(new Paragraph(s4, font3));
c4.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
c4.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
c4.setColspan(1);// 跨1列
c4.setBorder(0);
c4.setMinimumHeight(28);
PdfPCell c5 = new PdfPCell(new Paragraph(s5, font3));
c5.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
c5.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
c5.setColspan(2);// 跨2列
c5.setBorder(0);
c5.setMinimumHeight(28);
PdfPCell c6 = new PdfPCell(new Paragraph(s6, font3));
c6.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
c6.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
c6.setColspan(2);// 跨2列
c6.setBorder(0);
c6.setMinimumHeight(28);
PdfPCell c7 = new PdfPCell(new Paragraph(s7, font3));
c7.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
c7.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
c7.setColspan(1);// 跨1列
c7.setBorder(0);
c7.setMinimumHeight(28);
table.addCell(c1);
table.addCell(c2);
table.addCell(c3);
table.addCell(c4);
table.addCell(c5);
table.addCell(c6);
table.addCell(c7);
}
void addPDFTable2(PdfPTable table, Font font3, String s1, String s2, String s3, String s4, String s5) {
//添加表头
PdfPCell c1 = new PdfPCell(new Paragraph(s1, font3));
c1.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
c1.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
c1.setColspan(1);// 跨2行
c1.setBorder(0);
c1.setMinimumHeight(28);
PdfPCell c2 = new PdfPCell(new Paragraph(s2, font3));
c2.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
c2.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
c2.setColspan(1);// 跨2列
c2.setBorder(0);
c2.setMinimumHeight(28);
PdfPCell c3 = new PdfPCell(new Paragraph(s3, font3));
c3.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
c3.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
c3.setColspan(1);// 跨2列
c3.setBorder(0);
c3.setMinimumHeight(28);
PdfPCell c4 = null;
if (s4!=null&&!s4.isEmpty()) {
c4 = new PdfPCell(new Paragraph(s4, font3));
c4.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
c4.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
c4.setColspan(1);// 跨1列
c4.setBorder(0);
c4.setMinimumHeight(28);
}
PdfPCell c5 = new PdfPCell(new Paragraph(s5, font3));
c5.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中
c5.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
c5.setColspan(3);// 跨2列
c5.setBorder(0);
c5.setMinimumHeight(28);
table.addCell(c1);
table.addCell(c2);
table.addCell(c3);
if (c4 != null) {
table.addCell(c4);
}
table.addCell(c5);
}
}
这个是我调试好的pdf模板 本地调试Test
PdfUtil pdfUtil = new PdfUtil("D:/","testPDF.pdf",false);
//1.插入数据生成pdf文件
pdfUtil.setPdf(detailList,moneyList,memberCheckTime, Title, realname, beforemoney, overmoney, totalordermoney, totalmoney,img,photoimg);
会在本地D盘生成一个testPDF文件 setpdf方法里面的参数test的时候可以写死数据不用传参数
调试完pdf模板之后吧数据库和前端传过来的数据塞入pdf模板里面并下载pdf文件就好了
@RequestMapping(value = "/importPdf", produces = "application/json; charset=utf-8")
public ResponseEntity<byte[]> importPdf(HttpServletRequest request ,String MemberId,String beginDate,String endDate,Integer billMonth,String memberCheckTime,String title,String realName,String beforemoney,String overmoney,String totalordermoney,String totalmoney,String img,String photoimg) {
//1.在服务器上生成pdf文件 2.下载服务器上的pdf文件
Result<Object> resultDetail = new Result<>();
Result<Object> resultMoney = new Result<>();
//1.从Redis拿出参数
ComManagerVo manager = (ComManagerVo) rt.opsForValue().get(request.getAttribute("CurrentId"));
//1.数据库拿出数据
resultDetail = crmMemberBillService.getCrmMemberBillDetail(manager, MemberId, beginDate, endDate, billMonth);
resultMoney = crmMemberBillService.getCrmMemberMoney(manager, MemberId, beginDate, endDate, billMonth);
List<Map<String, Object>> detailList = (List<Map<String, Object>>) resultDetail.getData();
List<Map<String, Object>> moneyList = (List<Map<String, Object>>) resultMoney.getData();
//1.前端get请求 处理中文乱码
String realname = "";
String Title = "";
try {
realname = URLDecoder.decode(realName, "UTF-8");
Title = URLDecoder.decode(title, "UTF-8");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//1.保存服务器路径和文件名 false为是否为返利 可以不管
PdfUtil pdfUtil = new PdfUtil("D:/",""+realname+""+Title+"PDF.pdf",false);
//1.插入数据生成pdf文件
pdfUtil.setPdf(detailList,moneyList,memberCheckTime, Title, realname, beforemoney, overmoney, totalordermoney, totalmoney,img,photoimg);
//2.读取文件名
String fileName =realname+Title+"PDF.pdf";
File file = new File("D:/"+fileName);
String fileName1 = "";
try {
//2.处理中文 不然下载下来的文件名没有中文
fileName1 = new String(file.getName().getBytes("utf-8"),"ISO-8859-1");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//2.设置请求头内容,告诉浏览器代开下载窗口
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("attachment",fileName1);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
try {
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(new File("D:/"+fileName)),headers, HttpStatus.CREATED);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
前端get请求
//get请求传中文处理
window.location.href =
baseUrl + "/crm/member/importPdf?token=" + Cookies.get("token")+"&&billMonth="+billMonth+"&&beginDate="+beginDate
+"&&endDate="+endDate+"&&MemberId="+MemberId+"&&title="+encodeURI(encodeURI(title))+"&&realName="+encodeURI(encodeURI(realName))+"&&beforemoney="+beforemoney
+"&&overmoney="+overmoney+"&&totalordermoney="+totalordermoney+"&&totalmoney="+totalmoney+"&&memberCheckTime="+memberCheckTime+"&&img="+img
+"&&photoimg="+photoimg;
前端按钮调用get请求就可以下载pdf文件啦!
实现效果图如下
pdf文件以客户名称加title命名 因为list为空 所以客户销售明细表格没有显示出来。
OK 完成!