动态jsp转pdf文件
程序员文章站
2022-07-06 23:32:07
...
最近需要做一个功能,把jsp页面转成pdf,jsp页面有动态填充的数据,网上找了一些资料,基本上都是纯html页面数据转pdf,达不到动态填充数据的要求,结合网上查询的资料,动手改造一下jsp动态数据转pdf并下载文件。
调用的方法:
上面下载的方法中,使用了两步,第一步先把需要生成pdf的页面生成文件后存放在某个磁盘目录,再然后从磁盘里下载文件,有兴趣的朋友可以尝试下能否直接在生成pdf的时候输出到浏览器下载文件。服务端动态取出数据后,jsp页面采用el表达式设置相应的值即可。字体文件太大,系统上传不了,自行网上下载。
这里有个坑提示下大家,转成pdf的页面如果一行文字太长,最后生成的pdf会自动截断后面显示不下的文字,这里提供一个勉强的解决方案,在jsp页面<head>标签中写如下样式,即生成的pdf默认为A4纸的尺寸,可以让文字显示全一些。也可以设置为A1,A2,但是好像并没什么作用,网上查了一些资料说是要修改源码包代码,重新自定义大小,比较麻烦。另外待生成的页面必须严格遵守w3c规范,标签必须关闭,否则生成一定出错。
首先准备需要依赖的maven包和字体文件。 <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>core-renderer</artifactId> <version>R8</version> </dependency> 字体文件:simsun.ttc
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.http.HttpServletResponse; import org.xhtmlrenderer.pdf.ITextFontResolver; import org.xhtmlrenderer.pdf.ITextRenderer; import com.lowagie.text.DocumentException; import com.lowagie.text.pdf.BaseFont; /** * html转pdf工具 * */ public class TtmlToPdfUtil { /** * 把URL转换为PDF * @param url 需要生成pdf的页面url * @param filePath 生成的pdf存放目录 */ public static void htmlToPdf(String url, String filePath){ try { File outFile = new File(filePath); if (!outFile.exists()) { outFile.getParentFile().mkdirs(); } OutputStream os = new FileOutputStream(filePath); ITextRenderer renderer = new ITextRenderer(); renderer.setDocument(url); String fontPath = "/simsun.ttc";//字体 // 解决中文支持问题 ITextFontResolver fontResolver = renderer.getFontResolver(); fontResolver.addFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); renderer.layout(); renderer.createPDF(os); os.flush(); os.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 下载 * @param response * @param filePath */ public static void downloadPdf(HttpServletResponse response, String filePath) { try { File file = new File(filePath); InputStream inputStream = new FileInputStream(file); OutputStream os = response.getOutputStream(); byte[] b = new byte[1024]; int length; while ((length = inputStream.read(b)) > 0) { os.write(b, 0, length); } inputStream.close(); file.delete();//下载完后删除 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
调用的方法:
/** * 下载 * @param request * @param response * @param stuId * @throws Exception */ @RequestMapping("/downStuPdf") public void downpdf(HttpServletRequest request, HttpServletResponse response,Integer stuId) throws Exception{ Student stu = stuService.get(stuId); String fileName = stu.getName+".pdf";//生成的文件名称 response.setCharacterEncoding("UTF-8");//设置相应内容的编码格式 response.setHeader("Content-Disposition","attachment;filename="+new String(fileName.getBytes("GBK"), "ISO8859-1")); response.setContentType("application/pdf");//定义输出类型 //http://127.0.0.1:8080/stu/getStuInfo.do TtmlToPdfUtil.htmlToPdf(ServerContext.getLocalUrl()+"getStuInfo.do?stuId="+stuId, fileName); TtmlToPdfUtil.downloadPdf(response, fileName); } /** * 动态赋值信息到页面 * @return */ @RequestMapping("/getStuInfo") public ModelAndView stuInfo(Integer stuId) { Map<String, Object> map = new HashMap<String, Object>(); //姓名和年龄从数据库取,这里测试 // Student stu = stuService.get(stuId); map.put("name", "张三"); map.put("age", 20); return new ModelAndView("student.jsp", map); }
上面下载的方法中,使用了两步,第一步先把需要生成pdf的页面生成文件后存放在某个磁盘目录,再然后从磁盘里下载文件,有兴趣的朋友可以尝试下能否直接在生成pdf的时候输出到浏览器下载文件。服务端动态取出数据后,jsp页面采用el表达式设置相应的值即可。字体文件太大,系统上传不了,自行网上下载。
这里有个坑提示下大家,转成pdf的页面如果一行文字太长,最后生成的pdf会自动截断后面显示不下的文字,这里提供一个勉强的解决方案,在jsp页面<head>标签中写如下样式,即生成的pdf默认为A4纸的尺寸,可以让文字显示全一些。也可以设置为A1,A2,但是好像并没什么作用,网上查了一些资料说是要修改源码包代码,重新自定义大小,比较麻烦。另外待生成的页面必须严格遵守w3c规范,标签必须关闭,否则生成一定出错。
<style> body{font-family:SimSun;} @page{size:A4;margin:0;} </style>
推荐阅读