工作中碰到的坑,而且网上关于这方面的资料很少,就拿出来 和大家分享一下,希望大家少走弯路
使用iText生成PDF文档,文档中带有图片和表格
具体实现:
我用的是maven项目管理工具,虽说maven已经很流行了,但是仍然有一些jar包是maven不支持的, 比如这个iText,
解决办法就是我们自己把官方jar包打包成maven形式,
首先先下这个iTextAsian.jar下到某个地方(比如: D://), 然后执行(执行之前先确认maven的环境变量classpath是否有配置)
mvn install:install-file -DgroupId=com.lowagie -DartifactId=itextasian -Dversion=1.0 -Dpackaging=jar -Dfile=d:/itextasian.jar
这样就把maven打包到了本地的maven仓库中,并且version为1.0
然后在项目中添加maven的pom配置:
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itextasian</artifactId>
<version>1.0</version>
</dependency>
然后开始编写生产pdf的代码,
方法返回值是文件名,至于为什么要返回,后面在做附件的时候会用到
try {
logger.error("exportPDF is starting..............");
response.setHeader("content-Type", "application/pdf");
String fileName = resp.getMainOrderNo()+"预订单.pdf";
String filepath = System.getProperty("java.io.tmpdir");//系统默认的文件路径
String fileLocalName = filepath + fileName; //本地新建一个pdf的文件名
File file = new File(fileLocalName);
FileOutputStream fos = new FileOutputStream(file);
response.setHeader("Content-Disposition", "attachment;filename="+new String(fileName.getBytes("gb2312"), "iso8859-1"));//浏览器头设置
Document document = new Document(PageSize.A4);
if(type.equals(DOWNLOAD_PDF)){
PdfWriter.getInstance(document, response.getOutputStream());//用于返回页面下载
}else if(type.equals(SEND_PDF)){
PdfWriter.getInstance(document, fos);//用于邮件附件获取
}
document.open();
BaseFont bfChi = BaseFont.createFont(FONTPATH, BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);//字体
Font fontNormal = new Font(bfChi, 12, Font.NORMAL); //设置字体颜色格式
Font fontWhite = new Font(bfChi, 12, Font.NORMAL); //设置第二种字体
fontWhite.setColor(BaseColor.WHITE);//设置字体颜色
PdfPTable table = new PdfPTable(4);
table.setWidthPercentage(100);
table.setWidthPercentage(100);
Image img = Image.getInstance(getClass().getResource("/static/img/jinjiangIcon.jpg")); //项目静态文件中的图片,因为是logo,所以是不变的
img.scaleAbsolute(mmTopx(25), mmTopx(10)); //图片的大小控制,将像素转换成毫米
document.add(img);
genOderBasicInfo(resp, fontNormal,fontWhite, table);
document.add(table);
document.close();
fos.close();
return fileLocalName;
} catch (DocumentException e) {
logger.error("exportPDF is error................."+ e);
return "";
} catch (IOException e) {
logger.error("exportPDF is error................."+ e);
return "";
}
表格生成的方法:zh是做个采样截取一小部分:
private void genOderBasicInfo(DistributorOrderDetailResponse resp, Font fontNormal, Font fontWhite, PdfPTable table) {
String k ="订单编号:;产品名称:;套餐名称:";
List<String> dataList = new ArrayList<String>();
dataList.add(resp.getMainOrderNo());
dataList.add(resp.getPackName());
dataList.add(resp.getCombName());
createCell(k.split(";"), dataList, fontNormal,fontWhite, table, 3,Element.ALIGN_LEFT);
}
抽离的方法:
private void createCell(String[] k, List<String> dataList, Font fontNormal, Font fontWhite, PdfPTable table, int colspanNum, int align) {
if(k.length < 1 || dataList.size()<1) return;
for (int i = 0; i < k.length; i++) {
PdfPCell c = new PdfPCell(new Paragraph (k[i],fontWhite));
c.setBackgroundColor(new BaseColor(138,43,226));
c.setVerticalAlignment(Element.ALIGN_MIDDLE);
table.addCell (c);
PdfPCell cell1 = new PdfPCell (new Paragraph (dataList.get(i),fontNormal));
cell1.setColspan (colspanNum);
cell1.setHorizontalAlignment(align);
cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
table.addCell (cell1);
}
}
毫米转厘米的方法:
/**
* 毫米转像素
* @param mm
* @return
*/
public static float mmTopx(float mm){
mm = (float) (mm *3.33) ;
return mm ;
}
到这步,基本上导出到页面的pdf就有了,但是注意,因为pdfWrite是通过流操作写到了httpServletResponse中,
所以在页面上不能通过ajax操作来获取,我用的是页面form表单提交,controller层返回指定页面就可以了。
然而这里还有一个坑, 就是中文的问题,这里会一直报错:Font 'STSongStd-Light' with 'UniGB-UCS2-H' is not recognized. 错误,
原因是itext版本较高,itextasian由于重新打包, 报错的那个包换了名字,所以在itext执行时找不到这个语言包。
解决办法就是去http://sourceforge.net/projects/itext/files/,去这里下载最新的extrajars里的itextasian,
然后覆盖当前maven仓库中的旧版的就好.
至此,完成pdf导出功能