接之前的PDF转换,需求批量PDF导出压缩包
注意一下依赖版本
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.9</version>
</dependency>
itextpdf和xmlworker要保持一致,不然可能会报错
Controller层:
jsp视图的接口:
@RequestMapping(value = "/zyOpenProFinishPrint/{processInstanceId}/{projectId}") public String zyOpenProFinishPrint(final @PathVariable String processInstanceId, final @PathVariable int projectId, HttpServletRequest request, HttpServletResponse response, final Model model) throws BizException { //通过ID获取项目信息 ZyProjectInfo project = zyProjectInfoService.getZyProjectAmountById(projectId); //转账信息 ZyProjectEnd qry = new ZyProjectEnd(); qry.setProjectId(new Long(projectId)); ZyProjectEnd vo = zyProjectEndService.getByProjectId(qry); //收入信息 ZyJSalesContract zyJSalesContract = new ZyJSalesContract(); zyJSalesContract.setConType("0"); zyJSalesContract.setProjectId(new Long(projectId)); List<ZyJSalesContract> zyJSalesContracts = zyJSalesContractService.getListPrint(zyJSalesContract); //收入信息--合计 BigDecimal totalContractAmount = new BigDecimal(0);//合同金额 BigDecimal finalPriceTaxTotal = new BigDecimal(0);//审定价(含税) BigDecimal finalPrice = new BigDecimal(0);//审定价(不含税) BigDecimal sumAmount = new BigDecimal(0);//累计收款 BigDecimal totalProcessAmount = new BigDecimal(0);//累计进度收入 BigDecimal confirmProcessAmount = new BigDecimal(0);//已确认收入 BigDecimal monthProcessAmount = new BigDecimal(0);//本月结转收入 for(ZyJSalesContract str : zyJSalesContracts){ totalContractAmount = new BigDecimal(str.getTotalContractAmount()).add(totalContractAmount); finalPriceTaxTotal = str.getFinalPriceTaxTotal().add(finalPriceTaxTotal); finalPrice = str.getFinalPrice().add(finalPrice); sumAmount = str.getSumAmount().add(sumAmount); totalProcessAmount = str.getNoTaxPrice().add(totalProcessAmount); confirmProcessAmount = str.getConfirmProcessAmount().add(confirmProcessAmount); monthProcessAmount = str.getMonthProcessAmount().add(monthProcessAmount); } //成本信息 省略。。。。 OperateTemplete templete = new HttpTemplete(request) { protected void doSomething() throws BizException { str = "/zy/finance/completion_transfer_print"; } }; return templete.operateModel(); }
@RequestMapping("/downPdf") public void downloadPdf(final WfTask task, HttpServletRequest request, HttpServletResponse response) throws Exception{ String checkedIds = task.getCheckedIds(); String [] controlNo = checkedIds.split(","); List<String> controlNoList = new ArrayList(Arrays.asList(controlNo)); if(controlNoList.size() > 10){ throw new BizException("每次最多导出10条!!"); } Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyymmddHHmmss"); String url =request.getScheme()+"://"+ request.getServerName() + ":" + request.getServerPort() + request.getContextPath();//项目路径 // String Imagepath = request.getSession().getServletContext().getRealPath("/images/zy/yz_logo.png");//获取图像在项目中的路径 String Imagepath = url + "/static/images/zy/yz_logo.png";//获取图像在项目中的路径 System.out.println(Imagepath); List<String> fileNameList = new ArrayList<>(); List<ByteArrayInputStream> inputStreamList = new ArrayList<>(); response.setContentType("application/octet-stream"); //如果输出的是中文名的文件,在此处就要用URLEncoder.encode方法进行处理 // response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("测试", "UTF-8") +".zip"); response.setHeader("Content-Disposition", "attachment;filename=" + sdf.format(date) +".zip"); for(int i=0; i<controlNoList.size(); i++){ ZyProjectInfo bo = zyProjectInfoService.getZyProByControlNo(controlNoList.get(i)); String html = url + "/zy/zyCompletionTransferPrint/zyOpenProFinishPrint/0/"+ bo.getProjectId().toString(); String fileName = bo.getProjectName() + "完工转账.pdf"; fileNameList.add(fileName); String result = PdfUtils.parseURL2PDFFile(html); // 设置输出的格式 result = java.net.URLDecoder.decode(result, "ISO-8859-1");//如果跨域需设置解码 ByteArrayInputStream inStream = new ByteArrayInputStream( result.getBytes("ISO-8859-1")); InputStream inputStream = inStream; ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteArrayInputStream inputStreamAll = PdfUtils.addWordAndImg(inputStream, bos, Imagepath); inputStreamList.add(inputStreamAll); } //压缩流 ByteArrayInputStream inputStreamAll2 = zip(inputStreamList,fileNameList); //循环取出流中的数据 byte[] b = new byte[2048]; int len; try { while ((len = inputStreamAll2.read(b)) > 0) response.getOutputStream().write(b, 0, len); inputStreamAll2.close(); } catch (IOException e) { e.printStackTrace(); } }
/** * pdf流转为压缩流 * @param inputStreamList * @param fileNameList * @return * @throws IOException */ public ByteArrayInputStream zip(List<ByteArrayInputStream> inputStreamList, List<String> fileNameList) throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(outputStream)); for (int i=0; i<inputStreamList.size(); i++) { BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStreamList.get(i)); ZipEntry ze = new ZipEntry(fileNameList.get(i)); zipOutputStream.putNextEntry(ze); byte[] buffer = new byte[1024]; int len; while ((len = bufferedInputStream.read(buffer)) > 0) { zipOutputStream.write(buffer, 0, len); } bufferedInputStream.close(); } zipOutputStream.closeEntry(); zipOutputStream.flush(); zipOutputStream.close(); return new ByteArrayInputStream(outputStream.toByteArray()); }
PdfUtils:
/** * 根据URL提前blog的基本信息,返回结果 * @param url * @return * @throws Exception */ public static String[] extractHtmlInfo(String url) throws Exception { /*这里为什么用数组,是因为返回的时候不仅可以返回选择的html, 还有从document提取其他的信息单独存在数组里返回,然后利用iText在pdf里面组装数据,可以在网上查*/ String[] info = new String[1]; // 直接把URL解析成document,然后调用document.html()解析为html org.jsoup.nodes.Document doc = Jsoup.connect(url).get(); // 此doc.select是用来选择完整的html中某一部分这里为第一个div的css为entry的部分,所以你的html上要有div的class为entry哦 org.jsoup.nodes.Element entry = doc.select("div.entry").first(); info[0] = entry.html(); return info; } /** * 直接通过得到html来取得想要的部分html * @param html * @return * @throws Exception */ public static String[] extractHtmlInfo2(String html) throws Exception { String[] info = new String[1]; // 把html转换为document org.jsoup.nodes.Document doc = Jsoup.parse(html); // 此doc.select是用来选择完整的html中某一部分这里为第一个div的css为entry的部分,所以你的html上要有div的class为entry哦 org.jsoup.nodes.Element entry = doc.select("div.entry").first(); info[0] = entry.html(); return info; } /** * 把String 转为 InputStream * @param content * @return */ public static InputStream parse2Stream(String content) { try { ByteArrayInputStream stream = new ByteArrayInputStream( content.getBytes("UTF-8")); return stream; } catch (Exception e) { return null; } } /** * 直接把网页内容转为PDF文件 * @param * @throws Exception */ public static String parseURL2PDFFile(String html) throws Exception { String result = ""; ByteArrayOutputStream baos = null; Document doc = null; try { Rectangle rectPageSize = new Rectangle(PageSize.A4); doc = new Document(rectPageSize);// 可配其余4个参数,如(rectPageSize,60,60,60,60)页面边距 baos = new ByteArrayOutputStream();//构建字节输出流 PdfWriter pdfWriter = PdfWriter.getInstance(doc, baos);//将PDF文档对象写入到流 pdfWriter.setViewerPreferences(PdfWriter.HideToolbar); doc.open(); String[] blogInfo = extractHtmlInfo(html); /*html文件转换为pdf文档 AsianFontProvider()函数是用来解决XMLWorkerHelper.getInstance().parseXHtml()转pdf中文不显示问题*/ XMLWorkerHelper.getInstance().parseXHtml(pdfWriter,doc,parse2Stream(blogInfo[0]), (InputStream) null, new AsianFontProvider()); if (doc != null) { doc.close(); } result = new String(baos.toByteArray(), "ISO-8859-1");//转字符串设置编码 result = java.net.URLEncoder.encode(result, "ISO-8859-1");//如果跨域需设置编码 } catch (Exception e) { e.printStackTrace(); } finally { if (baos != null) { try { baos.close(); } catch (IOException e) { e.printStackTrace(); } } } return result; } /** * pdf添加完工转账格式的图片和文字 * @param imagePath * @throws IOException * @throws DocumentException */ public static ByteArrayInputStream addWordAndImg(InputStream input, ByteArrayOutputStream output, String imagePath) throws IOException, DocumentException { BaseFont baseFont = null; try { baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED); } catch (DocumentException e) { e.printStackTrace(); } PdfReader reader = new PdfReader(input); PdfStamper stamper = new PdfStamper(reader, output); PdfContentByte page = stamper.getOverContent(1); //将文字贴入pdf page.beginText(); page.setFontAndSize(baseFont,10); BaseColor coler = new BaseColor(0, 0, 0); page.setColorFill(coler); page.setTextMatrix(470,800); //设置文字在页面中的坐标 page.showText("上海中移信息技术有限公司"); page.endText(); //将图片贴入pdf // Image image = Image.getInstance("E:\\pdf\\yz_logo.png"); Image image = Image.getInstance(imagePath); image.scaleToFit(137, 35); image.setAbsolutePosition(0, 780); //设置图片在页面中的坐标 page.addImage(image); stamper.close(); reader.close(); input.close(); ByteArrayInputStream inputStream = new ByteArrayInputStream(output.toByteArray()); return inputStream; }
效果如下: