java web 导出PDF聊天记录

来源:互联网 发布:黄金价格数据库 编辑:程序博客网 时间:2024/06/05 16:08

 最近几天,项目要求一个小需求,用PDF格式导出聊天记录。虽然之前没有自己实现过,但是觉得网上这种例子应该很多,于是找了找。例子很多,但是这个坑也是挺多的。主要是使用iText 和flying saucer实现,xmlworker不知道怎么的,我本地一直导出的PDF没有内容,就暂时没有使用。

下面说下我自己的实现过程,以此记录下吧:

1.需求描述:

选择客服,可以该客服负责的多个客户的聊天记录,保留原有聊天记录样式

2.思路:

1)保留原有样式,如果自己向PDF里写的话,很不容易实现,所以想到应该用H5。

2)用JSP动态生成H5页面

3)多个客户要生成多个PDF文件,如果要下载的话,应该打包下载

4)循环每个客户的H5页面,生成PDF,先临时存放到服务器上,再Zip打包下载后删除


  需求很简单,思路也很简单的哈。。但是这样做,其实问题也挺多的。

3.问题:

1)每个H5都要解析,如果页面很大的话或者H5比较多的话,运行时间会比较长

2)PDF文件本身很大,先生成在服务器上,再打包下载,也会增加时间

解决思路《暂时在项目组还未实现》

1)多个文件,启用多个线程去分别运行

2)直接用流的形式,进行zip打包


下面粘贴一些自己实现的主要代码:

这是生成PDF的方法。这里主要遇到的问题是解决中文字体不显示的问题。因为我本地是win电脑,可以使用win自带的字体,本地测试没问题,但是放到服务器上就傻眼了,不显示中文了。然后看到网上说可以使用iTextAsian.jar这个第三方字库jar包,就高兴的去使用了。如果说自己向PDF里写内容的话,这个jar包是没问题的。但是我使用了ITextTenderer去读取H5这个方法,看源码正好和那个方法冲突。最后没辙,只能把简体中文字体包,打包到项目中。。。。。

*需要注意的是,如果读取H5要使用中文,必须在页面中设置字体。还有一些问题,是页面中的链接地址,必须是绝对地址或者是程序中给出。如果不是的话,程序会尝试多次去寻找链接,很费时间。。最后也是最重要一点,解析的HTML必须为XHTML,就是格式必须规范。如果不规范,就会解析异常的



public void createPDF(String destPath,String htmlAddress) throws IOException, DocumentException{
<span style="white-space:pre"></span>//destPath  服务器临时目录地址OutputStream os = new FileOutputStream(destPath);           <span style="white-space:pre"></span>ITextRenderer renderer = new ITextRenderer();renderer.setDocument(htmlAddress);ITextFontResolver fontResolver = renderer.getFontResolver();   <span style="white-space:pre"></span> //解决中文乱码问题//1.使用window自带中文字体/*fontResolver.addFont("C:/WINDOWS/Fonts/SIMSUN.TTC", BaseFont.IDENTITY_H,                     BaseFont.NOT_EMBEDDED);  */
<span style="white-space:pre"></span>//找到项目中的简体中文字体包URL url = this.getClass().getResource("/");fontResolver.addFont(url.toString(), BaseFont.IDENTITY_H,                     BaseFont.NOT_EMBEDDED); renderer.layout();renderer.createPDF(os);}


后面就是一些打包压缩输出的代码了


/** * 打包zip压缩文件 * @param files * @param baseName * @param zos * @throws IOException */private void zipFile(List<File> files,String baseName,ZipOutputStream zos) throws IOException{for (File file : files) {zos.putNextEntry(new ZipEntry(baseName+file.getName()));FileInputStream fis = new FileInputStream(file);byte[] buf = new byte[1024];int len = 0;while((len=fis.read(buf))!=-1){zos.write(buf, 0, len);}fis.close();}}


设置返回头,用流的方式返回给浏览器

<span style="white-space:pre"></span>response.setContentType("APPLICATION/OCTET-STREAM");response.setHeader("Content-Disposition", "attachment;filename="+getZipFileName());ZipOutputStream zos;try {zos = new ZipOutputStream(response.getOutputStream());zipFile(files, "", zos);zos.close();//删除生成的PDFfor (File file : files) {file.delete();}} catch (IOException e) {log.error("导出聊天记录PDF异常",e);}


代码真的很少,但是要想按照自己的需求去实现,坑还是挺多的。如果你生成的页面太大了的话,这个工具是不会自动帮你折行的,所以也需要给页面设置个大小。


在页面中加上这个,表示页面是A4的大小。


好啦,给上个结果图看看。也欣慰下哈


0 0