好久没写博客了,不是没东西写而是犯懒不想写,最近实在积累太多不写点担心全丢了,反正前一阵子的东西时找不回来了啦,赶紧趁有时间、有激情、有记忆记点是点吧。好啦,罗里吧嗦到这里,言归正传。
最近弄一项目,要求把人的基本信息和各项事迹弄成一个简历,并且导出为word、html、pdf三种格式。导出为word和html都使用的freemarker,生成pdf使用的flying saucer技术,这些技术都比较娴熟了,网上的资料也比较多,这里根据自己的实际情况记载一下,以及做的过程中遇到的一些问题。
生成word这篇文件已经介绍过了,这里就不赘述了。这里说生成html文件。
生成html文件使用的技术和生成word是一样的,流程和模式也是一样的。
1、创建模板文件:写一个符合条件和样式要求的html页面或者jsp页面,然后将其中的具体内容使用EL进行格式化(具体的可以看生成word的那篇,讲的比较详情)。我这里的基本内容如下(内容比较多,节选):
<%--基本信息 --%> <tr> <td class="resume-tit" >姓 名</td> <td width="112" >${field2}</td> <td class="resume-tit" >性 别</td> <td width="112" >${field3}</td> <%--电子照片 --%> <td width="120" align="center" rowspan="5"> <img width="120" height="150" src="${field30}" /> </td> </tr> <%--个人基本事迹 --%> <#if (table4List?size>0)> <tr> <td class="resume-tit">获奖情况</td> <td colspan="4"> <ul class="jlitem"> <#list table4List as t4> <li>${t4.order}、 <b>成果名称</b>:${t4.field3}<br /> <b>获奖名称及等级</b>:${t4.field4} <b>本人排名</b>:${t4.field5}</li> </#list> </ul> </td> </tr> </#if>
这里有几个说明点:
a、基本信息其实还有很多,个人基本事迹也有4个列表,这里只是截取其中一个比较有代表性的。
b、在freemarker中,可以使用<#if>标签进行判断。因为并不是每个人都有获奖的情况,若是没有那么在简历中获奖情况这块就不应该再显示。
c、获取list的长度,用size属性,结构:table4List?size,而且结合if使用时,一定要用括号将table4List?size括起来(形如:<#if (table4List?size>0)>),不然相当于没有判断。
d、循环list,使用<#list>标签,各个属性值的获取参照放进去时候的赋值(第三步赋值有具体说明)
2、修改后缀名:修改第一步中的html/jsp文件的后缀名,改成ftl格式。
3、读取模板文件需要的数据:根据主键序号从数据库中读取基本信息,并放到一个map中进行返回。
基本属性直接使用key-value放到map中,如将姓名为wjl的放到map中,第一步中姓名的代替符是${field2},也就是field2,那么:map.put(”field2“,”wjl”),这样页面中显示的就是wjl了。
有循环的,需要先将基本内容放到map中,然后将map放到list里,再将list放到需要返回的map中,具体操作看代码。
/*** * 该方法用来组装数据 * @param id:专家序号 * @param flag:1-word 2-html 3-pdf,主要是用来区分图片显示的问题 * */ public List readData(String id,int flag) { if(id==null || id.trim().length()<=0){return null;} /** 用于组装word页面需要的数据 */ Map<String, Object> dataMap = new HashMap<String, Object>(); List list = null; try{ //1、获取基本信息 StringBuffer sql = new StringBuffer(); sql.append("select field1,field2,field3,field4,field5,field6,field7,field8,field9,field10,") .append("field11,field12,field13,field14,field15,field16,field17,field18,field19,field20,") .append("field21,field22,field23,field24,field25,field26,field27,field28,field29,") .append("(select filepath from S_ACCESSORIES where id=field13) as field30 ") .append("from table1 ") .append("where field1="+id); // System.out.println(sql); List<Object[]> expertsList = execSQL.selectQuery2(sql.toString()); String fileContent=""; Object[] obj = null; if(expertsList!=null && expertsList.size()>0){ obj = expertsList.get(0);//只取一条 for(int i=0;i<obj.length;i++){ if(obj[i]!=null){ fileContent = obj[i].toString(); } dataMap.put("field"+(i+1),fileContent); fileContent="";//置空 } //出生日期格式调整 String birthday = dataMap.get("field5").toString(); if(birthday!=null && birthday.trim().length()>0){ birthday = com.wjl.util.Time.formatStringDateToYYYYMMDD(birthday); dataMap.put("field5",birthday); } //图片路径 String picture = dataMap.get("field30").toString(); if(picture!=null && picture.trim().length()>0){//说明有值 if(flag==3){//说明是导出为pdf,那么需要先生成html,此时文件加载使用绝对路径 picture = "file:///"+picture; }else{//导出为word、html,需要生成base64编码的图片 String prefix = picture.substring(picture.lastIndexOf(".")+1); picture = getImageStr(picture);//将图片变成base64编码 if(picture!=null && picture.trim().length()>0){ //说明是html格式,需要为base64编码的展示添加前缀否则显示不出来,word格式的可以直接显示 if(flag==2)picture = "data:image/"+prefix+";base64,"+picture; }else picture=""; } }else picture=""; dataMap.put("field30",picture); } //获奖情况 sql.delete(0,sql.length()); sql.append("select field1,field2,field3,field4,field5 ").append("from table4 ").append("where field2="+id); List<Object[]> prizeList = execSQL.selectQuery2(sql.toString()); List<Map<String, Object>> table4List=new ArrayList<Map<String,Object>>(); if(prizeList!=null && prizeList.size()>0){ for(int i=0;i<prizeList.size();i++){ Map<String, Object> map=new HashMap<String, Object>(); obj = prizeList.get(i); map.put("order", (i+1));//序号(与模板文件中list各个属性一一对应) map.put("field3", obj[2]);//成果名称 map.put("field4", obj[3]);//获奖名称及等级 map.put("field5", obj[4]);//本人排名 table4List.add(map); } } dataMap.put("table4List",table4List); list = new ArrayList(); list.add(dataMap); }catch(Exception e){ e.printStackTrace(); return null; } return list; } @SuppressWarnings("unchecked") //执行SQL public List<Object[]> selectQuery2(final String sql) throws Exception { log.debug("执行sql语句: " + sql); List<Object[]> result=null; try { result = (List<Object [] > ) getHibernateTemplate().execute(new HibernateCallback() { public Object doInHibernate(Session arg0) throws HibernateException, SQLException { return arg0.createSQLQuery(sql).list(); } }); } catch (Exception e) { System.out.println("ERROR:" + e.getMessage()); log.info("执行sql:[" + sql + "]失败:" + e.getMessage()); log.error("执行sql:[" + sql + "]失败:" + e.getMessage(), e); throw e; } if(result!=null && result.size()>0){ return result; }else{ return null; } } /** * 将字符串类型的日期进行格式化,返回格式化之后字符串类型的日期 * @param String strDate:字符串格式的日期 * @return 字符串类型格式化后的日期,如:2016.06.05 * **/ public static String formatStringDateToYYYYMMDD(String strDate){ if (strDate == null) return ""; SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");// 实例化模板对象 SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy.MM.dd");// 实例化模板对象 Date d = null ; try{ d = sdf1.parse(strDate) ; // 将给定的字符串中的日期提取出来 }catch(Exception e){ // 如果提供的字符串格式有错误,则进行异常处理 e.printStackTrace() ;// 打印异常信息 logger.info(e); } return sdf2.format(d);//按照规定格式进行格式化 } /** * 该方法用来将指定的文件转换成base64编码 * @param path:图片路径 * **/ private String getImageStr(String path){ //1、校验是否为空 if(path==null || path.trim().length()<=0){return "";} //2、校验文件是否为目录或者是否存在 File picFile = new File(path); if(picFile.isDirectory() || (!picFile.exists())) return ""; //3、校验是否为图片 try { BufferedImage image =ImageIO.read(picFile); if (image == null) { return ""; } } catch(IOException ex) { ex.printStackTrace(); return ""; } //4、转换成base64编码 String imageStr = ""; try { byte[] data = null; InputStream in = new FileInputStream(path); data = new byte[in.available()]; in.read(data); BASE64Encoder encoder = new BASE64Encoder(); imageStr = encoder.encode(data); } catch (Exception e) { imageStr=""; e.printStackTrace(); } return imageStr; }
说明点:
a、图片显示问题。(详情点这里)
b、模板文件中有的EL,返回的map中必须put进去否则会报错。如:模板文件中有个${field100},map中并没有put("field10",field100的内容)那么就会报错,生成的html也会说格式错误。
4、生成文件:使用模板文件生成html文件。
/** * @Desc:生成word/html文件 * @param dataMap:数据集合 * @param templateFilePath:模板文件所在目录 * @param templateFileName:模板文件名称 * @param docFilePath:生成的word文档的具体目录,包括目录+名称+.doc * @param boolean:true-创建成功 false:创建失败 */ public boolean createFile(Map dataMap,String templateFilePath,String templateFileName,String docFilePath){ try { Configuration configuration = new Configuration();//创建配置实例 configuration.setDefaultEncoding("UTF-8");//设置编码 configuration.setDirectoryForTemplateLoading(new File(templateFilePath));//加载模板文件 Template template = configuration.getTemplate(templateFileName);//获取模板 //创建文件 File outFile = new File(docFilePath); //如果输出目标文件夹不存在,则创建 if (!outFile.getParentFile().exists()){ outFile.getParentFile().mkdirs(); } //该文件已经存在,那么删除,避免更新了数据但是简历没有更新的情况发生 if(outFile.isFile() && outFile.exists()){ outFile.delete(); } //将模板和数据模型合并生成文件 Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8")); //生成文件 template.process(dataMap, out); //关闭流 out.flush(); out.close(); return true;//返回文件路径 } catch (Exception e) { e.printStackTrace(); return false; } }
5、组合:将获取数据和生成文件组合起来,并提供下载。
//将基本信息导出到word或者pdf public String exportToFile() throws Exception{ HttpServletRequest request = ServletActionContext.getRequest(); Object userInfo = request.getSession().getAttribute("userInfo"); if (userInfo == null) throw new Exception("用户信息获取失败:userInfo=null"); try{ String id = request.getParameter("id"); Integer flag= Integer.parseInt(request.getParameter("flag"));//1-导出到word 2-导出为HTML 3-导出为pdf if(id!=null){ //1、获取添加到word/html中的数据 List dataList = readData(id,flag); //2、生成word/html String path = ""; //word文档目录 String docFilePath = "D"+File.separator+":"+File.separator+"bfp"+File.separator+"temp"; if(WebAppConfig.app("tempPath")!=null && WebAppConfig.app("tempPath").trim().length()>0){ docFilePath = WebAppConfig.app("tempPath"); } String prefix="JM"; if(WebAppConfig.app("docPrefix")!=null && WebAppConfig.app("docPrefix").trim().length()>0){ prefix = WebAppConfig.app("docPrefix"); } boolean result2=false; if(dataList!=null && dataList.size()>0){ Map dataMap = (Map)dataList.get(0);//集合数据 //word文档名称 String fileName = docFilePath+File.separator+prefix+System.currentTimeMillis(); switch(flag){ case 1: path = fileName+".doc";//word文档所在目录 break; case 2://html case 3://pdf,生成pdf之前必须生成html tempWordName = "experts.ftl";//模板名称 path = fileName+".html";//word文档所在目录 break; default:break; } //生成word或者html文件 result2 = createFile(dataMap,templateFilePath,tempWordName,path);//生成word if(flag==3 && result2==true){//生成pdf并且word已经生成 //7、生成pdf //param1:pdf所在目录 param2:word/html所在目录 result2 = createPDFByHtml(fileName+".pdf",path); //result2 = officeToPdf(new File(fileName+".pdf"),new File(path));//使用openoffice生成pdf path = fileName+".pdf"; } //8、提供下载 fileDown(new File(path)); } } }catch(Exception e){ e.printStackTrace(); } return null; } /** * 进行下载 * @param file:File对象,需要进行下载的对象 * */ public void fileDown(File downFile){ try{ if (!downFile.exists()) throw new Exception("没有找到您需要的资源:" + downFile.getName()+"!"); HttpServletResponse response = ServletActionContext.getResponse(); FileInputStream in = new FileInputStream(downFile); // response.setContentType("application/msword"); response.setHeader("Content-Disposition","attachment;filename="+ new String(downFile.getName().getBytes("GBK"),"ISO-8859-1")); //response.reset();//解决:getWriter() has already been called for this response的问题 OutputStream outputStream = response.getOutputStream(); int i = 0; byte b[] = new byte[1024]; while ((i = in.read(b)) != -1) {//读取文件 outputStream.write(b, 0, i);//写入到页面提供下载 } outputStream.flush(); outputStream.close(); outputStream=null; response.flushBuffer(); }catch(Exception e){ e.printStackTrace(); } }
相关推荐
本篇文章将深入探讨如何在Java中使用FreeMarker生成带有盖章的PDF合同文件。 首先,让我们了解FreeMarker的基本概念。FreeMarker是一个基于模板的语言,它与Java代码分离,允许开发者用简单的模板语法来表示数据。...
标题“使用FreeMarker生成Html静态文件”暗示了我们将探讨如何利用FreeMarker将动态数据转化为静态的HTML页面。这一过程通常涉及以下几个步骤: 1. **配置FreeMarker**: 首先,我们需要在Java项目中引入FreeMarker...
以下是关于如何使用FreeMarker生成Word文件的一些关键知识点: 1. **FreeMarker模板语言**:FreeMarker使用一种简单的模板语言,允许开发者通过定义变量和控制结构(如循环和条件语句)来动态地插入数据。在模板中...
FreeMarker是一个强大的模板引擎,常用于动态生成HTML、XML或其他文本格式的文件,包括Word文档。在Java开发中,利用FreeMarker生成Word文件可以极大地提高效率,尤其在需要批量生成或者自定义模板的情况下。以下是...
Freemarker是一个强大的模板引擎,常用于Java应用中动态生成HTML、XML或其他文本格式的文件。这个示例是关于如何使用Freemarker来生成XML文件,对于初学者来说,理解这个过程有助于掌握Freemarker的基本用法和XML的...
本文将详细解析一个具体的使用案例:如何利用Freemarker根据模板生成文件,特别是Java环境下生成Hibernate的配置文件(*.hbm.xml)。此案例不仅展示了Freemarker的基本用法,还涉及到了自定义类、接口以及模板加载...
- `freemarker`目录下的例子可能包括基础的模板文件(如`template.ftl`)和对应的Java测试类,展示了如何使用FreeMarker生成HTML,你可以通过阅读这些例子了解具体用法。 总的来说,FreeMarker是Java Web开发中...
总的来说,这个"springboot整合freemarker生成静态html的demo"项目展示了如何在SpringBoot应用中集成FreeMarker,以及如何通过模板和字符串两种方式生成HTML。这有助于我们构建更高效、更易于维护的Web应用,将视...
Java中的Freemarker是一个强大的模板引擎,常用于生成动态HTML、XML或文本文件,而这里我们讨论的是如何利用Freemarker生成复杂的Word文档。在Java应用中,有时我们需要生成结构化且内容丰富的Word文档,例如报告、...
3. **处理模板**:使用Freemarker API的`Configuration`和`Template`类,将数据模型应用到模板上,生成HTML字符串。 4. **调用wkhtmltox**:通过Java绑定库,将生成的HTML字符串转换为PDF。 5. **保存PDF**:将生成...
`Freemarker`是一个强大的模板引擎,通常用于动态生成HTML、XML等文本格式,而将`Freemarker`与HTML模板结合生成PDF,可以充分利用HTML的易编辑性和富文本特性,为用户提供高质量的文档输出。下面我们将深入探讨如何...
FreeMarker是一个广泛使用的开源Java模板引擎,主要用于生成HTML、XML等Web内容,但也可以用于生成任何类型的文本,包括Java代码。这篇博客文章“使用FreeMarker生成java代码”深入探讨了如何利用FreeMarker来自动化...
通过这个例子,我们可以看到FreeMarker如何实现动静分离,以及如何在Eclipse环境中使用它生成HTML文件。这个过程有助于提高开发效率,因为设计师可以专注于HTML模板的设计,而程序员只需关注数据处理和业务逻辑。在...
Freemarker是一个强大的模板引擎,常用于动态生成HTML、XML或其他文本格式的文件,比如在Java开发中,它被广泛应用于生成代码、邮件模板、报表等。本篇将详细介绍如何利用Freemarker来生成Java代码。 一、...
Freemarker是一个强大的模板引擎,常用于动态生成HTML、XML和其他文本格式的文件,包括Excel。在Java开发中,利用Freemarker生成Excel文件能够极大地提高效率,特别是处理复杂表格时,其灵活性尤为突出。本示例重点...
在这个Eclipse项目中,你可能需要创建一个Java类来提供数据模型,然后使用Freemarker API来加载模板文件,并结合数据模型生成HTML。这通常涉及到以下几个步骤: 1. 创建数据模型(如Java对象)。 2. 初始化...
- FreeMarker生成的Word文档默认基于HTML,因此模板应遵循HTML结构,但也可以使用OpenXML SDK创建更接近原生Word的文档。 - 模板文件的编码应与Java代码的编码一致,避免出现乱码问题。 - 谨慎处理模板中的动态...
FreeMarker 是一个强大的模板引擎,常用于生成动态HTML、XML或其他文本格式的文件。在Java Web开发中,它被广泛应用于自动生成代码,减少重复的手动编写工作,提高开发效率。本篇将深入探讨如何使用FreeMarker来生成...
你需要在这里定义数据模型,加载Freemarker模板,设置输出文件路径,然后调用Freemarker的API来生成文档。具体步骤如下: - 创建一个`Configuration`对象,配置Freemarker的模板目录。 - 加载Freemarker模板文件,...