通过freemarker+iText生成pdf和doc文件
来源:互联网 发布:unity3d打字游戏 编辑:程序博客网 时间:2024/05/05 02:10
0、通过上一篇已经能够跑起来将ftl展示成html,这里进一步将ftl模版文件生成pdf和doc
1、公共类,初始化freemarker,从request里面获取参数,组装参数等
import freemarker.template.Configuration;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import javax.servlet.http.HttpServletRequest;import java.util.Enumeration;import java.util.HashMap;import java.util.Map;/** * Created by Administrator on 2016/11/2. */public class FreemarkerBase { protected final Log logger = LogFactory.getLog(getClass()); private Configuration freemarker_cfg = null; /** * 获取freemarker的配置. freemarker本身支持classpath,目录和从ServletContext获取. */ protected Configuration getFreeMarkerCFG(){ if (null == freemarker_cfg){ freemarker_cfg = new Configuration(); freemarker_cfg.setDefaultEncoding("utf-8"); //ftl是放在classpath下的一个目录 freemarker_cfg.setClassForTemplateLoading(this.getClass(), "/freemarker/"); } return freemarker_cfg; } //取出req中的参数,这里最好用guawa等做一下参数验证,否则会报错,展示不合理 protected Map getRequestParams(HttpServletRequest req, String type){ String imgPath = req.getSession().getServletContext().getRealPath(""); Map<String, Object> map = new HashMap<>(); Enumeration<String> paramNames = req.getParameterNames(); // 通过循环将表单参数放入键值对映射中 while(paramNames.hasMoreElements()) { String key = paramNames.nextElement(); String value = req.getParameter(key); //word:如果ftl绑定的图片,需要根目录的路径 if("doc".equals(type) && (value.toLowerCase().contains(".jpg") || value.toLowerCase().contains(".png"))){ value = req.getSession().getServletContext().getRealPath("/upload") + "/" + value; } //pdf:这里我写的是访问连接的根目录,因为不知道为什么我写全路径就不行,怪异了。 else if("pdf".equals(type) && (value.toLowerCase().contains(".jpg") || value.toLowerCase().contains(".png"))){ value = "http://localhost:8080/upload/" + value; } // System.out.println(value); map.put(key, value); } return map; }}
2、公共方法
/* *下面两个是doc和pdf的公共方法 *///生成临时文件方法//templateFileName 模版名,即ftl文件名,见上面的show.ftl//params ftl文件内的参数绑定//htmlFilePath 文件生成目录//suffix 后缀,eg:.doc .pdf 等等private String createTemplateDownFile(String templateFileName, Map params, String htmlFilePath, String suffix){ String htmlFileName = "temp" + (int) (Math.random() * 100000) + suffix; try{ Template t = getFreeMarkerCFG().getTemplate(templateFileName); File mkPath = new File(htmlFilePath); if (!mkPath.exists()){ mkPath.mkdirs(); } File file = new File(htmlFilePath + "/" + htmlFileName); Writer out = new OutputStreamWriter(new FileOutputStream(file), "utf-8"); t.process(params, out); }catch (TemplateException e){ logger.error("freemarker模版参数绑定错误 " + templateFileName,e); e.printStackTrace(); }catch (IOException e){ logger.error("html生成失败 " + htmlFileName,e); e.printStackTrace(); } return htmlFileName;}//下载方法private void downLoad(HttpServletResponse resp, String allPath, String suffix){ resp.setCharacterEncoding("utf-8"); //这里是一个生成名字的方法,我是用了一个我们自己的公共类,按照日期生成名字 String name = DateUtil.dateToStr(new Date(), 5 ); //根据后缀判断resp的题头文件 if("html".equals(suffix)){ resp.setContentType("text/html"); } else if("doc".equals(suffix)){ resp.setContentType("application/msword"); } else if("pdf".equals(suffix)){ resp.setContentType("application/PDF"); } resp.addHeader("Content-Disposition", "attachment;filename=" + name + suffix); //开始下载 File file = new File(allPath); try { InputStream fin = new FileInputStream(file); ServletOutputStream out = resp.getOutputStream(); byte[] buffer = new byte[512]; // 缓冲区 int bytesToRead = -1; // 通过循环将读入的文件的内容输出到浏览器中 while((bytesToRead = fin.read(buffer)) != -1) { out.write(buffer, 0, bytesToRead); } } catch (IOException e) { e.printStackTrace(); }}
3、生成doc文件很简单,不用额外导入什么jar
//主方法@RequestMapping("downDoc")public void downDoc(HttpServletRequest request, HttpServletResponse resp){ String rootPath = request.getSession().getServletContext().getRealPath("/doc"); String fileName = createTemplateDownFile("show.ftl" , getRequestParams(request, "doc"), rootPath, ".doc"); String allPath = rootPath + "/" + fileName; //下载公共方法 downLoad(resp, allPath, ".doc");}
4、生成pdf文件,pdf我是通过ftl生成html文件,再通过这个静态的html文件生成pdf,这样不知道是不是冗余,当时是测试html的下载,所以直接拿来用了。
引入jar:
<dependency> <groupId>com.lowagie</groupId> <artifactId>itext</artifactId> <version>2.1.7</version></dependency><dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf</artifactId> <version>9.0.9</version></dependency>
有歧义的jar,不引入
<!-- 2.*直接跳到了5.*,结构不大一样,网上demo多是2.*的,所以暂时先用了 --><dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.4.3</version></dependency><!-- 我用bootstarp的css文件这里一直报错,后来用了上面的,是基于java,2.1css渲染的 --><dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>core-renderer</artifactId> <version>R8</version></dependency><!-- 用了自己的文字,如果用itext的需要这个jar展示中文,不过我一直也搞不好报错,所以就用自己的了 --><dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version></dependency>
代码:
/** * 下载pdf文件 * @param request * @param resp */@RequestMapping("downPdf")public void downPdf(HttpServletRequest request, HttpServletResponse resp){ //eg:c:/workspace/项目/doc/ String rootPath = request.getSession().getServletContext().getRealPath(""); String fileName = createTemplateDownFile("show.ftl" , getRequestParams(request, "pdf"), rootPath + "/html", ".html"); //根目录+下设文件夹名+文件名 String allPath = rootPath + "/html/" + fileName; try { //输入html的路径 String url = new File(allPath).toURI().toURL().toString(); //输出pdf路径,这里偷懒替换了html的名字改为pdf名字 String newFileName = fileName.substring(0, fileName.lastIndexOf(".")) + ".pdf"; String outputFile = rootPath + "/pdf/" + newFileName; OutputStream os = new FileOutputStream(outputFile); ITextRenderer renderer = new ITextRenderer(); renderer.setDocument(url); // 解决中文支持问题,我是 copy了系统的宋体放到了项目里面,itext是直接扫描到classpath下面的,所以是相对路径,绝对也是可以的。还有,千万要注意,这里用simsun字体,也就是宋体,所以在ftl中的body标签要加样式<body style="font-family: SimSun">,而且ftl非常严格,meta标签最后一般没有“/>”,会报错提醒这里格式不对。 ITextFontResolver fontResolver = renderer.getFontResolver(); fontResolver.addFont("/font/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); // 解决图片的相对路径问题,因为从request中提取参数的时候已经加上了域名全路径,这里就不写文件全路径了 // renderer.getSharedContext().setBaseURL("file:/C:xxxx"); renderer.layout(); renderer.createPDF(os); os.close(); //下载公共方法 downLoad(resp, outputFile, ".pdf"); } catch (MalformedURLException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); }}
5、最后
- 浏览器访问:localhost:8080/downPdf.do?host=qrcode.jpg或者localhost:8080/downDoc.do?host=qrcode.jpg就自动下载word和pdf文档了。
- 不知道能不能直接ftl生成pdf,网上相关资料也不多,正好这个html下载下来判断样式,就先这样吧。
- 还有一个问题是生成的pdf、html、doc因为要下载,所以都没有写删除的方法,暂时也不知道怎么清理。想到可以存入数据库,存入路径和名字需要的时候下载,还可以有删除的方法……再说。
- 这里是记录为主,图片的路径和jar的选择,样式的判断费了很大的劲,所以记录一下以防以后使用。
- 配合上一篇文章食用才可,springmvc的总体配置就不写了。
最后再重申一下,千万要注意,这里用simsun字体,也就是宋体,所以在ftl中的body标签要加样式style=”font-family: SimSun”,而且ftl非常严格,meta标签最后一般没有“/>”,会报错提醒这里格式不对。
1 0
- 通过freemarker+iText生成pdf和doc文件
- Freemarker+IText生成pdf文件
- Java使用Freemarker和iText生成PDF文件
- Itext生成PDF文件
- Freemarker+Flying sauser +Itext 整合生成PDF
- Freemarker、Flying sauser 、Itext 整合生成 pdf
- 用iText生成PDF文件
- Itext 生成 pdf文件使用方法:
- iText生成PDF报表文件
- 使用iText生成pdf文件
- 关于iText生成PDF文件
- 使用iText生成PDF文件
- 使用freemaker和itext从html模板生成pdf文件
- Java通过freemarker生成pdf文件并盖章
- 使用iText生成doc
- 使用Aspose.word生成.pdf和.doc(word)报告文件
- 生成PDF文件的Java库iText
- Java应用iText动态生成PDF文件
- 我就问,见过比这还有诚意的前端学习路线图吗?
- Redis单机主从高可用性优化
- DAY16:leetcode #33 Search in Rotated Sorted Array
- csrf(xsrf)跨站点请求伪造
- python cx_Oracle模块的安装
- 通过freemarker+iText生成pdf和doc文件
- iOS 协议
- laravel 利用migrate 创建数据表
- css3 animation
- 如果像写代码一样写Gradle脚本
- Linux vmstat命令实战详解
- Tomcat JNDI配置
- esxi如何使用cdrom启动
- Linux无法识别移动设备(U盘、移动硬盘)的问题