注意一下依赖版本
<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;
}
效果如下:
PDF效果图: