java导出pdf
在项目开发中,产品的需求越来越奇葩啦,开始文件下载都是下载为excel的,做着做着需求竟然变了,要求能导出pdf。导出pdf倒也不是特别大的问题关键就是麻烦。
导出pdf我知道的一共有3中方法:
方法一:利用模板导出,但是首先编辑模板的工具不好找,现有的国外的工具要收费,所以放弃了这个。
方法二:利用HTML页面导出,奈何自己不会写HTML,前端忙没时间帮忙写。本着求人不如靠己的想法就选择了第三种比较麻烦的方法,自己用table画。
方法三:自己用纯代码画格式(可调字体大小,颜色,对复杂没有规则的数据都可以)
首先必须导入的依赖有

<!--导出pdf所需包--><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.10</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency>

然后就是一顿代码输出
先把效果贴上

然后是代码部分

@ApiOperation(value = "导出")@PostMapping("/download")@SneakyThrows(Exception.class)public void download(@RequestBody @Valid FumigationDTO fumigationDTO, HttpServletResponse response, HttpServletRequest request) {// 防止日志记录获取session异常request.getSession();// 设置编码格式response.setContentType("application/pdf;charset=UTF-8");response.setCharacterEncoding("utf-8");String fileName = URLEncoder.encode("下载的PDF名称", "UTF-8");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".pdf");fumigationService.download(fumigationDTO, response);}

业务层

@Overridepublic void download(FumigationDTO fumigationDTO, HttpServletResponse response) throws IOException {//要下载的数据查询数据部分我去掉了有需要自己根据业务取FumigationDowloadVO fumigationDowloadVO = new FumigationDowloadVO();// 定义全局的字体静态变量Font titlefont;Font headfont;Font keyfont = null;Font textfont = null;Font content = null;// 最大宽度try {// 不同字体(这里定义为同一种字体:包含不同字号、不同style)BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);titlefont = new Font(bfChinese, 16, Font.BOLD);headfont = new Font(bfChinese, 14, Font.BOLD);keyfont = new Font(bfChinese, 10, Font.BOLD);textfont = new Font(bfChinese, 15, Font.NORMAL);content = new Font(bfChinese, 10, Font.NORMAL);} catch (Exception e) {e.printStackTrace();}BaseFont bf;Font font = null;try {//创建字体bf = BaseFont.createFont( "STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);//使用字体并给出颜色font = new Font(bf,20,Font.BOLD,BaseColor.BLACK);} catch (Exception e) {e.printStackTrace();}Document document = new Document(new RectangleReadOnly(842F, 595F));try {PdfWriter.getInstance(document,response.getOutputStream());//打开生成的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;//第一行cell = new PdfPCell(new Paragraph("熏蒸备案编码",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setFixedHeight(30);table.addCell(cell);cell = new PdfPCell(new Paragraph(fumigationDowloadVO.getXzbm()));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph("熏蒸备案时间",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph(CheckVerifyUtil.dateToString4(fumigationDowloadVO.getSqxzrq())));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph("申请备案单位",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph(fumigationDowloadVO.getDwmc(),content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);//第二行cell = new PdfPCell(new Paragraph("熏蒸作业库点",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setFixedHeight(30);table.addCell(cell);cell = new PdfPCell(new Paragraph(fumigationDowloadVO.getKdmc(),content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph("负责人",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph(fumigationDowloadVO.getFzr(),content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph("联系电话",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph(fumigationDowloadVO.getFzrdh(),content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);//第三行cell = new PdfPCell(new Paragraph("单据状态",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setFixedHeight(30);table.addCell(cell);cell = new PdfPCell(new Paragraph(shzt(fumigationDowloadVO.getShzt()),content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph("审核时间",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph(CheckVerifyUtil.dateToString5(fumigationDowloadVO.getShsj()),content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph(" ",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Paragraph(" ",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);// 设置表格的列宽和列数float[] widths2 = {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);//人员列表-第四行cell = new PdfPCell(new Paragraph("姓名",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setFixedHeight(20);table2.addCell(cell);cell = new PdfPCell(new Paragraph("职务",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table2.addCell(cell);cell = new PdfPCell(new Paragraph("职业资格",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table2.addCell(cell);cell = new PdfPCell(new Paragraph("身体状况",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table2.addCell(cell);cell = new PdfPCell(new Paragraph("熏蒸任务分工",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table2.addCell(cell);cell = new PdfPCell(new Paragraph("是否外包",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table2.addCell(cell);//人员列表数据-第五行if(fumigationDowloadVO.getProples().size() > 0){for (RecordFumigationPeople prople : fumigationDowloadVO.getProples()) {PdfPCell cell1 = new PdfPCell(new Paragraph(prople.getXm(), content));PdfPCell cell2 = new PdfPCell(new Paragraph(prople.getZw(), content));PdfPCell cell3 = new PdfPCell(new Paragraph(prople.getZyzg(), content));PdfPCell cell4 = new PdfPCell(new Paragraph(prople.getStzk(), content));PdfPCell cell5 = new PdfPCell(new Paragraph(prople.getXzrwfg(), content));PdfPCell cell6 = new PdfPCell(new Paragraph(prople.getSfwb(), 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);table2.addCell(cell1);table2.addCell(cell2);table2.addCell(cell3);table2.addCell(cell4);table2.addCell(cell5);table2.addCell(cell6);}}// 设置表格的列宽和列数float[] widths3 = {25f,25f,25f,25f,25f};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("仓房",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setFixedHeight(20);table3.addCell(cell);cell = new PdfPCell(new Paragraph("货位",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table3.addCell(cell);cell = new PdfPCell(new Paragraph("粮食品种",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table3.addCell(cell);cell = new PdfPCell(new Paragraph("计划熏蒸开始时间",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table3.addCell(cell);cell = new PdfPCell(new Paragraph("计划熏蒸结束时间",content));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table3.addCell(cell);if(fumigationDowloadVO.getDtls().size() > 0){for (RecordFumigationDtlVO dtl : fumigationDowloadVO.getDtls()) {PdfPCell cell1 = new PdfPCell(new Paragraph(dtl.getCfmc(), content));PdfPCell cell2 = new PdfPCell(new Paragraph(dtl.getHwmc(), content));PdfPCell cell3 = new PdfPCell(new Paragraph(dtl.getLspzmc(), content));PdfPCell cell4 = new PdfPCell(new Paragraph(CheckVerifyUtil.dateToString4(dtl.getJhxzksrq()), content));PdfPCell cell5 = new PdfPCell(new Paragraph(CheckVerifyUtil.dateToString4(dtl.getJhxzjsrq()), 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);table3.addCell(cell1);table3.addCell(cell2);table3.addCell(cell3);table3.addCell(cell4);table3.addCell(cell5);}}document.add(new Paragraph("\n"));document.add(new Paragraph("▋ 基本信息",content));document.add(new Paragraph("\n"));document.add(table);document.add(new Paragraph("\n"));document.add(new Paragraph("▋ 基本信息",content));document.add(new Paragraph("\n"));document.add(table2);document.add(new Paragraph("\n"));document.add(new Paragraph("▋ 熏蒸作业储粮粮情",content));document.add(new Paragraph("\n"));document.add(table3);//关闭文档document.close();} catch (DocumentException e) {e.printStackTrace();log.error("导出pdf失败:{}",e);}}

(二)2023-08-24 更新导出PDF无表格

效果:内容全部为代码实现

贴上代码:

@SneakyThrows@PostMapping("/rectification/notice/export")@ApiOperation("xxxx通知导出")public void registrationNoticeExport(@RequestBody InspectionPlanDtlListDTO reqParam, HttpServletRequest request, HttpServletResponse response) {request.getSession();if (StringUtils.isBlank(reqParam.getId())) {throw new CustomException("id不能为空");}String year = String.valueOf(Calendar.getInstance().get(Calendar.YEAR));ExpertSignInExportVO vo = inspectionProblemService.registrationNoticeExport(reqParam.getId());if(NoticeCoeEnum.getIdList().contains(vo.getId())){vo.setDate("2023年08月18日");}else {vo.setDate(DateUtil.date().toString(DatePattern.CHINESE_DATE_PATTERN));}// 检查单位List<InspectionPlanUnitVO> planUnitList = inspectionPlanUnitRelationMapper.selectByPlanId(vo.getPlanId());vo.setInspectionCompany(planUnitList.stream().map(InspectionPlanUnitVO::getUnitName).collect(Collectors.joining("、")));vo.setYear(year);Field[] fields = vo.getClass().getDeclaredFields();HashMap<String, String> dataMap = new HashMap<>(fields.length);for (Field field : fields) {field.setAccessible(true);dataMap.put("${" + field.getName() + "}", String.valueOf(field.get(vo)));}if (StringUtils.isNotBlank(vo.getInspectionTeamLeader()) || StringUtils.isNotBlank(vo.getInspectorPhone())) {dataMap.put("${inspectionTeamLeaderInfo}", String.format("(联系人:%s;联系电话:%s)",vo.getInspectionTeamLeader(), StringUtils.isNotBlank(vo.getOfficePhone()) " />.getOfficePhone() : vo.getInspectorPhone()));}dataMap.put("${attachmentNameStr}", "" + String.join("\n", vo.getAttachmentNameList()));//导出pdfPdfUtil.setResponseContentType(response, vo.getInspectedEnterprise() + vo.getPlanName() + "检查整改通知" + year);//PdfUtil.fillWordTemplate("template/rectification_notice.pdf", dataMap, response);PdfUtil.downloadPdf(dataMap,response);//String fileName = vo.getInspectedEnterprise() + vo.getPlanName() + "检查整改通知" + year;////导出excel//WordUtil.setResponseContentType(response, fileName);//WordUtil.fillWordTemplate("template/rectification_notice.docx", dataMap, response.getOutputStream(),Boolean.TRUE);}

导出pdf工具

public static void setResponseContentType(HttpServletResponse response, String fileName) throws UnsupportedEncodingException {response.setContentType("application/pdf");response.setCharacterEncoding("utf-8");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8") + ".pdf");response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");}public static void downloadPdf(Map<String,String> dataMap, HttpServletResponse response){// 定义全局的字体静态变量Font titlefont;Font headfont;Font keyfont = null;Font textfont = null;Font content = null;Font space = null;Font space1 = null;Font space2 = null;Font space3 = null;// 最大宽度try {// 不同字体(这里定义为同一种字体:包含不同字号、不同style)BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);titlefont = new Font(bfChinese, 16, Font.BOLD);headfont = new Font(bfChinese, 14, Font.BOLD);keyfont = new Font(bfChinese, 22, Font.BOLD);textfont = new Font(bfChinese, 15, Font.NORMAL);content = new Font(bfChinese, 16, Font.NORMAL);space = new Font(bfChinese, 5, Font.NORMAL);space1 = new Font(bfChinese, 20, Font.NORMAL);space2 = new Font(bfChinese, 20, Font.NORMAL);space3 = new Font(bfChinese, 3, Font.NORMAL);} catch (Exception e) {e.printStackTrace();}BaseFont bf;Font font = null;try {//创建字体bf = BaseFont.createFont( "STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);//使用字体并给出颜色font = new Font(bf,36,Font.BOLD, BaseColor.RED);} catch (Exception e) {e.printStackTrace();}Document document = new Document(new Rectangle(com.itextpdf.text.PageSize.A4));try {com.itextpdf.text.pdf.PdfWriter.getInstance(document, response.getOutputStream());//打开PDF文件document.open();//设置内容Paragraph paragraph = new Paragraph("深圳市粮食和物资储备保障中心", font);//居中设置paragraph.setAlignment(Element.ALIGN_CENTER);document.add(paragraph);//页眉横线document.add(new Paragraph("\n", space2));LineSeparator line = new LineSeparator(3f, 100, BaseColor.RED, Element.ALIGN_CENTER, 0f);document.add(line);document.add(new Paragraph("\n", space3));LineSeparator lineStart = new LineSeparator(1f, 100, BaseColor.RED, Element.ALIGN_CENTER, 0f);document.add(lineStart);document.add(new Paragraph("\n", space));String text = "深储整改〔 " + dataMap.get("${year}") + "〕" + dataMap.get("${sort}") + "号";Paragraph paragraph0 = new Paragraph(text, content);paragraph0.setAlignment(Element.ALIGN_RIGHT);document.add(paragraph0);document.add(new Paragraph("\n"));Paragraph paragraph1 = new Paragraph(dataMap.get("${inspectionCompany}") + "关于", keyfont);paragraph1.setAlignment(Element.ALIGN_CENTER);document.add(paragraph1);document.add(new Paragraph("\n", space));String concent = dataMap.get("${planName}") + "发现问题整改的通知";Paragraph paragraph2 = new Paragraph(concent, keyfont);paragraph2.setAlignment(Element.ALIGN_CENTER);document.add(paragraph2);document.add(new Paragraph("\n"));Paragraph paragraph3 = new Paragraph(dataMap.get("${qymc}") + ":", content);paragraph3.setAlignment(Element.ALIGN_LEFT);document.add(paragraph3);document.add(new Paragraph("\n", space));String concent1 = " 现将" + dataMap.get("${kdmc}") + dataMap.get("${planName}")+ "检查发现问题及整改要求转给你司,请严格按期限要求进行整改,并将整改落实情况(含佐证材料及附件)通过深圳市粮食和物资储备信息管理平台反馈我中心。";Paragraph paragraph4 = new Paragraph(concent1, content);//设置首行缩进paragraph4.setIndentationRight(2);document.add(paragraph4);document.add(new Paragraph("\n", space));Paragraph paragraph5 = new Paragraph("特此通知。", content);paragraph5.setIndentationRight(2);//右缩进2格document.add(paragraph5);document.add(new Paragraph("\n", space1));document.add(new Paragraph("\n", space1));//附件Paragraph paragraph6 = new Paragraph("附件:", content);paragraph6.setIndentationRight(2);//右缩进2格document.add(paragraph6);document.add(new Paragraph("\n", space));Paragraph paragraph7 = new Paragraph(dataMap.get("${attachmentNameStr}"), content);document.add(paragraph7);document.add(new Paragraph("\n", space1));document.add(new Paragraph("\n", space1));document.add(new Paragraph("\n", space1));//日期Paragraph paragraph8 = new Paragraph(dataMap.get("${date}"), content);//向右paragraph8.setAlignment(Element.ALIGN_RIGHT);document.add(paragraph8);document.add(new Paragraph("\n", space1));//落款Paragraph paragraph9 = new Paragraph(dataMap.get("${inspectionTeamLeaderInfo}"), content);paragraph9.setAlignment(Element.ALIGN_CENTER);document.add(paragraph9);//页尾横线document.add(new Paragraph("\n", space2));document.add(new Paragraph("\n", space2));LineSeparator lineEnd = new LineSeparator(3f, 100, BaseColor.RED, Element.ALIGN_CENTER, 0f);document.add(lineEnd);document.add(new Paragraph("\n", space3));LineSeparator lineEnd1 = new LineSeparator(1f, 100, BaseColor.RED, Element.ALIGN_CENTER, 0f);document.add(lineEnd1);//关闭文档document.close();} catch (Exception e) {e.printStackTrace();log.error("导出pdf失败:{}", e);}}

然后就可以了直接导出pdf。