public CustomApiResult<String> exportPdf(HttpServletRequest request, HttpServletResponse response) throws IOException {// 防止日志记录获取session异常request.getSession();// 设置编码格式response.setContentType("application/pdf;charset=UTF-8");response.setCharacterEncoding("utf-8");SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");String fileName = URLEncoder.encode("成品检验检验单" + dateFormat.format(new Date()), "UTF-8");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".pdf");// 表头idString id = request.getParameter("id");// 分录idString taskEntryId = request.getParameter("entryId");
// 数据DynamicObject dynamicObject = getPdfData(Long.valueOf(id), Long.valueOf(taskEntryId));download(response, dynamicObject);return CustomApiResult.success("成功");}
画pdf
public void download(HttpServletResponse response, DynamicObject data) throws IOException {// 定义全局的字体静态变量Font headfont;Font content;// 最大宽度try {// 不同字体(这里定义为同一种字体:包含不同字号、不同style)BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);headfont = new Font(bfChinese, 14, Font.BOLD);content = new Font(bfChinese, 10, Font.NORMAL);BaseFont bf;Font font;//创建字体bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);//使用字体并给出颜色font = new Font(bf, 20, Font.BOLD, new Color(0, 0, 0));headfont = new Font(bf, 10, Font.BOLD, new Color(0, 0, 0));Document document = new Document(new RectangleReadOnly(842F, 595F));//设置页边距 60:左边距,60:右边距,72:上边距,72:下边距document.setMargins(60, 60, 72, 72);PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());//添加页码writer.setPageEvent(new PdfPageUtil());//打开生成的pdf文件document.open();//设置内容Paragraph paragraph = new Paragraph("成品检验 检验单", font);paragraph.setAlignment(1);//引用字体document.add(paragraph);// --------任务分录---设置表格的列宽和列数float[] widths = {25f, 25f, 25f, 25f, 25f, 25f};PdfPTable table = new PdfPTable(widths);table.setSpacingBefore(20f);// 设置表格宽度为100%table.setWidthPercentage(100.0F);table.setHeaderRows(1);table.getDefaultCell().setHorizontalAlignment(1);PdfPCell cell = null;//第一行table.addCell(createCenteredCell("检验标准", 30, null, headfont));table.addCell(createCenteredCell(data.getString("eo45_standard_name"), 0, null, content));table.addCell(createCenteredCell("检验日期", 0, null, headfont));table.addCell(createCenteredCell(String.valueOf(data.getDate("eo45_check_date")), 0, null, content));table.addCell(createCenteredCell("检验人员", 0, null, headfont));table.addCell(createCenteredCell(data.getString("eo45_check_person"), 0, null, content));// 第二行table.addCell(createCenteredCell("生产厂家", 30, null, headfont));table.addCell(createCenteredCell(data.getString("eo45_suppliers"), 0, null, content));table.addCell(createCenteredCell("物料名称", 0, null, headfont));table.addCell(createCenteredCell(data.getString("eo45_material_names"), 0, null, content));table.addCell(createCenteredCell("物料规格", 0, null, headfont));table.addCell(createCenteredCell(data.getString("eo45_specifications"), 0, null, content));//第三行table.addCell(createCenteredCell("物料批次", 30, null, headfont));table.addCell(createCenteredCell(data.getString("eo45_material_batch"), 0, null, content));table.addCell(createCenteredCell("总数量", 0, null, headfont));table.addCell(createCenteredCell(data.getString("eo45_total"), 0, null, content));table.addCell(createCenteredCell("", 0, null, headfont));table.addCell(createCenteredCell("", 0, null, content));// --------检验详情---设置表格的列宽和列数float[] widths2 = {25f, 25f, 25f, 25f, 25f, 25f, 25f};PdfPTable table2 = new PdfPTable(widths2);table2.setSpacingBefore(20f);// 设置表格宽度为100%table2.setWidthPercentage(100.0F);table2.setHeaderRows(1);table2.getDefaultCell().setHorizontalAlignment(1);// 第一行table2.addCell(createCenteredCell("序号", 30, new Color(204, 204, 204), headfont));table2.addCell(createCenteredCell("检验项目", 0, new Color(204, 204, 204), headfont));table2.addCell(createCenteredCell("标准要求", 0, new Color(204, 204, 204), headfont));table2.addCell(createCenteredCell("检验方法及依据", 0, new Color(204, 204, 204), headfont));table2.addCell(createCenteredCell("抽样数量", 0, new Color(204, 204, 204), headfont));table2.addCell(createCenteredCell("实测结果", 0, new Color(204, 204, 204), headfont));table2.addCell(createCenteredCell("检验判定", 0, new Color(204, 204, 204), headfont));// 第二行开始循环数据DynamicObjectCollection item = data.getDynamicObjectCollection("eo45_zjy_task_item");Iterator var8 = item.iterator();int i = 0;while (var8.hasNext()) {i++;DynamicObject itemData = (DynamicObject) var8.next();PdfPCell cell1 = new PdfPCell(new Paragraph(String.valueOf(i), content));PdfPCell cell2 = new PdfPCell(new Paragraph(itemData.getString("eo45_project"), content));PdfPCell cell3 = new PdfPCell(new Paragraph(itemData.getString("eo45_standard_require"), content));PdfPCell cell4 = new PdfPCell(new Paragraph(itemData.getString("eo45_test_method"), content));PdfPCell cell5 = new PdfPCell(new Paragraph(itemData.getString("eo45_sample_qty"), content));JSONObject jsonObject = StringUtils.isNotEmpty(itemData.getString("eo45_actual_json"))? JSONObject.parseObject(itemData.getString("eo45_actual_json")) : new JSONObject();PdfPCell cell6 = new PdfPCell(new Paragraph("", content));String type = jsonObject.containsKey("type") ? jsonObject.getString("type") : "";// 根据json类型解析数据if ("number".equals(type)) {cell6 = new PdfPCell(new Paragraph(jsonObject.containsKey("value") ? jsonObject.getString("value") : "", content));} else if ("select".equals(type)) {JSONArray jsonArray = jsonObject.containsKey("option") ? JSONArray.parseArray(jsonObject.getString("option")) : null;if (jsonArray != null) {for (int j = 0; j < jsonArray.size(); j++) {JSONObject jsonObject1 = jsonArray.getJSONObject(j);if (jsonObject1.containsKey("selectStatus") && jsonObject1.getBoolean("selectStatus")) {cell6 = new PdfPCell(new Paragraph(jsonObject.getString("eo45_value_mapping"), content));}}}} else {cell6 = new PdfPCell(new Paragraph(jsonObject.getString("eo45_actual_json"), content));}PdfPCell cell7 = new PdfPCell(new Paragraph(itemData.getString("eo45_item_decide"), content));//单元格对齐方式cell1.setHorizontalAlignment(Element.ALIGN_CENTER);cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);cell1.setFixedHeight(20);//单元格垂直对齐方式cell2.setHorizontalAlignment(Element.ALIGN_CENTER);cell2.setVerticalAlignment(Element.ALIGN_MIDDLE);cell3.setHorizontalAlignment(Element.ALIGN_CENTER);cell3.setVerticalAlignment(Element.ALIGN_MIDDLE);cell4.setHorizontalAlignment(Element.ALIGN_CENTER);cell4.setVerticalAlignment(Element.ALIGN_MIDDLE);cell5.setHorizontalAlignment(Element.ALIGN_CENTER);cell5.setVerticalAlignment(Element.ALIGN_MIDDLE);cell6.setHorizontalAlignment(Element.ALIGN_CENTER);cell6.setVerticalAlignment(Element.ALIGN_MIDDLE);cell7.setHorizontalAlignment(Element.ALIGN_CENTER);cell7.setVerticalAlignment(Element.ALIGN_MIDDLE);table2.addCell(cell1);table2.addCell(cell2);table2.addCell(cell3);table2.addCell(cell4);table2.addCell(cell5);table2.addCell(cell6);table2.addCell(cell7);}// ------综合判定----设置表格的列宽和列数// 设置表格的列宽和列数float[] widths3 = {25f, 75f};PdfPTable table3 = new PdfPTable(widths3);table3.setSpacingBefore(20f);// 设置表格宽度为100%table3.setWidthPercentage(100.0F);table3.setHeaderRows(1);table3.getDefaultCell().setHorizontalAlignment(1);cell = new PdfPCell(new Paragraph("综合判定", headfont));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setFixedHeight(20);table3.addCell(cell);cell = new PdfPCell(new Paragraph(data.getString("eo45_decide"), content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table3.addCell(cell);for (int j = 0; j < 1; j++) {PdfPCell cell1 = new PdfPCell(new Paragraph("备注", headfont));String contentResult = "";// 富文本处理if (StringUtils.isNotBlank(data.getString("eo45_decide_result"))) {org.jsoup.nodes.Document documentResult = Jsoup.parse(data.getString("eo45_decide_result"));contentResult = documentResult.text();}PdfPCell cell2 = new PdfPCell(new Paragraph(contentResult, content));//设置居中cell1.setHorizontalAlignment(Element.ALIGN_CENTER);cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);cell1.setFixedHeight(20);cell2.setHorizontalAlignment(Element.ALIGN_CENTER);cell2.setVerticalAlignment(Element.ALIGN_MIDDLE);table3.addCell(cell1);table3.addCell(cell2);}document.add(table);document.add(table2);document.add(table3);//关闭文档document.close();} catch (DocumentException e) {log.error("导出pdf失败DocumentException:{}", e);} catch (Exception e) {log.error("导出pdf失败Exception:{}", e);}}private PdfPCell createCenteredCell(String value, float fixedHeight, Color color, Font font) {PdfPCell cell = new PdfPCell(new Paragraph(value, font));cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 设置背景色if (color != null) {cell.setBackgroundColor(color);}// 设置单元格高度if (fixedHeight != 0) {cell.setFixedHeight(fixedHeight);}return cell;}
工具类
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;import java.io.IOException;/*** @Author xx* @Date 2023/12/15 10:05* @Description: 导出pdf添加页数* @Version 1.0*/
public class PdfPageUtil extends PdfPageEventHelper {/*** 页眉*///public String header = "itext测试页眉";/*** 文档字体大小,页脚页眉最好和文本大小一致*/public int presentFontSize = 9;/*** 文档页面大小,最好前面传入,否则默认为A4纸张*/public Rectangle pageSize = PageSize.A4;// 模板public PdfTemplate total;// 基础字体对象public BaseFont bf = null;// 利用基础字体生成的字体对象,一般用于生成中文文字public Font fontDetail = null;/**** 无参构造方法.**/public PdfPageUtil() {}/**** 构造方法.** @param** @param presentFontSize* 数据体字体大小* @param pageSize* 页面文档大小,A4,A5,A6横转翻转等Rectangle对象*/public PdfPageUtil( int presentFontSize, Rectangle pageSize) {this.presentFontSize = presentFontSize;this.pageSize = pageSize;}public void setPresentFontSize(int presentFontSize) {this.presentFontSize = presentFontSize;}/**** 文档打开时创建模板*/@Overridepublic void onOpenDocument(PdfWriter writer, Document document) {// 共 页 的矩形的长宽高total = writer.getDirectContent().createTemplate(50, 50);}/****关闭每页的时候,写入页眉,写入'第几页共'这几个字。*/@Overridepublic void onEndPage(PdfWriter writer, Document document) {this.addPage(writer, document);}//加分页public void addPage(PdfWriter writer, Document document){//设置分页页眉页脚字体try {if (bf == null) {bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);}if (fontDetail == null) {fontDetail = new Font(bf, presentFontSize, Font.NORMAL);// 数据体字体}} catch (DocumentException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}// 1.写入页眉
// ColumnText.showTextAligned(writer.getDirectContent(),
// Element.ALIGN_LEFT, new Phrase(header, fontDetail),
// document.left(), document.top() + 20, 0);// 2.写入前半部分的 第 X页/共int pageS = writer.getPageNumber();//String foot1 = "第 " + pageS + " 页 /共";String foot1 = pageS +"/";Phrase footer = new Phrase(foot1, fontDetail);// 3.计算前半部分的foot1的长度,后面好定位最后一部分的'Y页'这俩字的x轴坐标,字体长度也要计算进去 = lenfloat len = bf.getWidthPoint(foot1, presentFontSize);// 4.拿到当前的PdfContentBytePdfContentByte cb = writer.getDirectContent();// 5.写入页脚1,x轴就是(右margin+左margin + right() -left()- len)/2.0FColumnText.showTextAligned(cb,Element.ALIGN_CENTER,footer,(document.rightMargin() + document.right()+ document.leftMargin() - document.left() - len) / 2.0F ,document.bottom() - 10, 0);cb.addTemplate(total, (document.rightMargin() + document.right()+ document.leftMargin() - document.left()) / 2.0F ,document.bottom() - 10); // 调节模版显示的位置}// //加水印
// public void addWatermark(PdfWriter writer){
// // 水印图片
// Image image;
// try {
// image = Image.getInstance("./web/images/001.jpg");
// PdfContentByte content = writer.getDirectContentUnder();
// content.beginText();
// // 开始写入水印
// for(int k=0;k<5;k++){
// for (int j = 0; j <4; j++) {
// image.setAbsolutePosition(150*j,170*k);
// content.addImage(image);
// }
// }
// content.endText();
// } catch (IOException | DocumentException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }/**** 关闭文档时,替换模板,完成整个页眉页脚组件*/@Overridepublic void onCloseDocument(PdfWriter writer, Document document) {// 关闭文档的时候,将模板替换成实际的 Y 值total.beginText();// 生成的模版的字体、颜色total.setFontAndSize(bf, presentFontSize);//页脚内容拼接 如 第1页/共2页//String foot2 = " " + (writer.getPageNumber()) + " 页";//页脚内容拼接 如 第1页/共2页String foot2 = String.valueOf(writer.getPageNumber() - 1);// 模版显示的内容total.showText(foot2);total.endText();total.closePath();}
}