首页 > 代码库 > java-web中生成文档(一)

java-web中生成文档(一)

基于Java的解决方案也是很多的,包括使用Jacob、Apache POI、Java2Word、iText等各种方式,其实在从Office 2003开始,就可以将Office文档转换成XML文件,这样只要将需要填入的内容放上${}占位符,就可以使用像Freemarker这样的模板引擎将出现占位符的地方替换成真实数据,这种方式较之其他的方案要更为简单。

举个项目中实际的例子,先编辑一个word文挡

技术分享

1:将文档另存为成xml格式:

技术分享

2:另存之后建议用 Editplus、Notepad++、Sublime等工具打开查看一下,因为有的时候你写的占位符可能会被拆开,这样Freemarker就无法处理 了。处理成如下图所示:

技术分享

3:然后另存为.ftl格式(选择支持所有的格式),好了非代码的部分完成,开始搭建自己的项目,我使用的服务器是Tomcat 7.0.52,myelcipse2014;如果是eclipse需要配置web.xml支持servlet3的注解,在搭建项目之前需要向项目中加入freemarker的JAR文件,可以通过下面的链接获得Freemarker的最新版本:http://freemarker.org/freemarkerdownload.html

我搭建的是一个maven 的项目,进入当中找到pom文件所需有的配置文件http://mvnrepository.com/artifact/org.freemarker/freemarker

技术分享

4.完成jsp的网页代码,当中要明白name的命名一定是与ftl文件中的值是对应的,这样才能取到值。上传jsp代码

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><html xmlns="http://www.w3.org/1999/xhtml"><head>  <base href="http://www.mamicode.com/">       <meta http-equiv="pragma" content="no-cache">    <meta http-equiv="cache-control" content="no-cache">    <meta http-equiv="expires" content="0">        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">    <meta http-equiv="description" content="This is my page">     <style type="text/css">      * { font-family: "微软雅黑"; }      .textField { border:none; border-bottom: 1px solid gray; text-align: center; }      #file { border:1px solid black; width: 80%; margin:0 auto; }      h1 input{ font-size:72px; }      td textarea { font-size: 14px; }      .key { width:125px; font-size:20px; }  </style>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>缴 费 通 知 单</title></head><body>  <form action="saveDocServlet.s" method="post"><div id="file" align="center">          <h1>缴 费 通 知 单</h1>          <hr/>    <table width="750" border="1">            <tr><td width="120" class="key">费项到期时间</td>                <td height="39" colspan="3"><input type="text" name="ecEndtimeCost" class="textField" value="http://www.mamicode.com/${param.ecEndtimeCost }" style="border:0px"/><span style="text-align:right">日</span></td>             </tr>              <tr>                  <td class="key">姓名</td>                  <td width="212"><input type="text" name="uname" class="textField" value="http://www.mamicode.com/${param.uname}" style="border:0px"/></td>                  <td width="80" class="key">房号:</td>                  <td width="355">                      <input type="text" name="room" value="http://www.mamicode.com/${param.room}" style="border:0px"/>                </td>              </tr>              <tr>                  <td class="key">电费:</td>                  <td><input type="text" name="ecElectricityFee" class="textField"  style="border:0px" value="http://www.mamicode.com/${param.ecElectricityFee }"/>元</td>                  <td class="key">水费:</td>                  <td><input type="text" name="ecWaterFee" class="textField" style="border:0px" value="http://www.mamicode.com/${param.ecWaterFee }"/>元</td>              </tr>              <tr>                  <td class="key">物业管理费:</td>                <td><input type="text" name="ecPropertyFee" class="textField" style="border:0px" value="http://www.mamicode.com/${param.ecPropertyFee }"/>元</td>                 <td class="key">停车费:</td>                  <td><input type="text" name="ecParkingFee" class="textField" style="border:0px" value="http://www.mamicode.com/${param.ecParkingFee }"/>元</td>             </tr>              <tr>                  <td height="39" colspan="4" class="key">                    合计金额:  <input name="text" style="border: 0px; width:5px " /> 万 <input name="text" style="border: 0px; width:5px " />    仟<input name="text" style="border: 0px; width:5px " />      佰  <input name="text" style="border: 0px; width:5px " />    拾    <input name="text" style="border: 0px; width:5px " />  元   <input style="border: 0px; width:5px " />   角   <input name="text" style="border: 0px; width:5px " />   分   &nbsp;&nbsp;小写:<input name="ecAssessment" style="border: 0px;  " value="http://www.mamicode.com/${param.ecAssessment }" /></td>              </tr>          </table>         <p >友情提醒:1、请业主在<input name="ecFeesDeadline" style="border: 0px;  " value="http://www.mamicode.com/${param.ecFeesDeadline }" />        日前来小区物业服务处缴费,如有不便可通知物业上门收费,</p>   <p >物业服务热线:027-86889888    ,超过规定月份未交的将按有关规定加收滞纳金。</p>  <p>2、如认为通知单上有错误,可到物业服务处查对,以电脑收费台帐上的金额为准。</p>        </br>  <p style=" position:relative left:600px">            <input name="text"  style="border: 0px; width:25px " /> 年<input name="text" style="border: 0px; width:25px " />         月 <input  name="text" style="border: 0px; width:25px " />        日</p>    </div>      <div align="center" style="margin-top:15px;">          <input type="submit" value="http://www.mamicode.com/保存Word文档" />      </div>    </form> </body></html>

(注意param这个el表达式对象不能用到word文档取值,保证name的值一致就行)

我在把spring-mvc中的控制器代码,给一份;如果你用servlet去写也可以,但是要支持webservice注解的需要用到servlet3.0,这是就需要去web.xml容器中写配置文件

技术分享

如果不支持就麻烦了,所以我使用springmvc的核心控制器写的,不多说了给代码

package com.controller.zy;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.util.Enumeration;import java.util.HashMap;import java.util.Map;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import com.lovo.util.WordGenerator;@Controllerpublic class MyServlet extends HttpServlet {    private static final long serialVersionUID = 1L;     @RequestMapping("/saveDocServlet.s")    protected void service(HttpServletRequest req, HttpServletResponse resp)              throws ServletException, IOException {          req.setCharacterEncoding("utf-8");          Map<String, Object> map = new HashMap<String, Object>();          Enumeration<String> paramNames = req.getParameterNames();          // 通过循环将表单参数放入键值对映射中          while(paramNames.hasMoreElements()) {              String key = paramNames.nextElement();              String value = req.getParameter(key);              map.put(key, value);          }                // 提示:在调用工具类生成Word文档之前应当检查所有字段是否完整          // 否则Freemarker的模板殷勤在处理时可能会因为找不到值而报错 这里暂时忽略这个步骤了          File file = null;          InputStream fin = null;          ServletOutputStream out = null;          try {              // 调用工具类WordGenerator的createDoc方法生成Word文档              file = WordGenerator.createDoc(map, "zhy");              fin = new FileInputStream(file);                            resp.setCharacterEncoding("utf-8");              resp.setContentType("application/msword");              // 设置浏览器以下载的方式处理该文件默认名为zhy.doc              resp.addHeader("Content-Disposition", "attachment;filename=zhy.doc");                            out = resp.getOutputStream();              byte[] buffer = new byte[512];  // 缓冲区              int bytesToRead = -1;              // 通过循环将读入的Word文件的内容输出到浏览器中              while((bytesToRead = fin.read(buffer)) != -1) {                  out.write(buffer, 0, bytesToRead);              }          } finally {              if(fin != null) fin.close();              if(out != null) out.close();              if(file != null) file.delete(); // 删除临时文件          }      }  }

5,还要有个工具类作为中间调用的方法使用,不用多想,代码是固定的,拿着改文件名就可以

package com.lovo.util;import java.io.File;  import java.io.FileOutputStream;  import java.io.IOException;  import java.io.OutputStreamWriter;  import java.io.Writer;  import java.util.HashMap;  import java.util.Map;    import freemarker.template.Configuration;  import freemarker.template.Template;    public class WordGenerator {      private static Configuration configuration = null;      private static Map<String, Template> allTemplates = null;            static {          configuration = new Configuration();          configuration.setDefaultEncoding("utf-8");          configuration.setClassForTemplateLoading(WordGenerator.class, "/com/lovo/ftl");          allTemplates = new HashMap<>();   // Java 7 钻石语法          try {              allTemplates.put("zhy", configuration.getTemplate("zhy.ftl"));          } catch (IOException e) {              e.printStackTrace();              throw new RuntimeException(e);          }      }        private WordGenerator() {          throw new AssertionError();      }        public static File createDoc(Map<?, ?> dataMap, String type) {          String name = "temp" + (int) (Math.random() * 100000) + ".doc";          File f = new File(name);          Template t = allTemplates.get(type);          try {              // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开              Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");              t.process(dataMap, w);              w.close();          } catch (Exception ex) {              ex.printStackTrace();              throw new RuntimeException(ex);          }          return f;      }    }  

到这里已经完成了代码,部署到服务器就可以使用了,希望能够帮到你。

 

java-web中生成文档(一)