java-web中生成文档(一)

基于Java的解决方案也是很多的,包括使用JacobApache 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="<%=basePath%>">

    <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="${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="${param.uname}" style="border:0px"/></td>
                <td width="80" class="key">房号:</td>
                <td width="355">
                    <input type="text" name="room" value="${param.room}" style="border:0px"/>
              </td>
            </tr>
            <tr>
                <td class="key">电费:</td>
                <td><input type="text" name="ecElectricityFee" class="textField"  style="border:0px" value="${param.ecElectricityFee }"/>元</td>
                <td class="key">水费:</td>
                <td><input type="text" name="ecWaterFee" class="textField" style="border:0px" value="${param.ecWaterFee }"/>元</td>
            </tr>
            <tr>
                <td class="key">物业管理费:</td>
                <td><input type="text" name="ecPropertyFee" class="textField" style="border:0px" value="${param.ecPropertyFee }"/>元</td>
                <td class="key">停车费:</td>
                <td><input type="text" name="ecParkingFee" class="textField" style="border:0px" value="${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="${param.ecAssessment }" />  元
                </td>
            </tr>
        </table>
        <p >友情提醒:1、请业主在<input name="ecFeesDeadline" style="border: 0px;  " value="${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="保存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;
@Controller
public 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;
    }  

}  

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

时间: 2024-10-17 16:22:08

java-web中生成文档(一)的相关文章

使用 Swagger 自动生成 ASP.NET Core Web API 的文档、在线帮助测试文档(ASP.NET Core Web API 自动生成文档)

对于开发人员来说,构建一个消费应用程序时去了解各种各样的 API 是一个巨大的挑战.在你的 Web API 项目中使用 Swagger 的 .NET Core 封装 Swashbuckle 可以帮助你创建良好的文档和帮助页面. Swashbuckle 可以通过修改 Startup.cs 作为一组 NuGet 包方便的加入项目.Swashbuckle 是一个开源项目,为使用 ASP.NET Core MVC 构建的 Web APIs 生成 Swagger 文档.Swagger 是一个机器可读的 R

MVC WEB api 自动生成文档

最近在一直在用webapi做接口给移动端用.但是让我纠结的时候每次新加接口或者改动接口的时候,就需要重新修改文档这让我很是苦恼.无意中发现.webapi居然有自动生成文档的功能....真是看见了救星啊. 在看了一些资料后发现,如果你的开发环境比较老的话像VS2010 VS2008 这样的你可能需要手动在nuGet去安装一个新的组件, 需要安装这一个组件来进行配置,安装完成后会多一个文件夹(因为这个版本较新可能会有依赖版本冲突) 如果你是2013的版本的话你在创建项目的时候默认就会有这个文件夹,当

ASP.NET Core 1.0 中使用 Swagger 生成文档

github:https://github.com/domaindrivendev/Ahoy 之前文章有介绍在ASP.NET WebAPI 中使用Swagger生成文档,ASP.NET Core 1.0中同样也支持. 依赖包 "dependencies": { "Swashbuckle.SwaggerGen": "6.0.0-rc1-final", "Swashbuckle.SwaggerUi": "6.0.0-rc

多模块Maven项目如何使用javadoc插件生成文档

需求 最近要对一个项目结构如下的Maven项目生成JavaDoc文档. Project |-- pom.xml |-- Module1 |   `-- pom.xml |-- Module2 |   `-- pom.xml |-- Module3 |-- pom.xml 这个就需要用到本文将要提出的一个Maven插件:javadoc. 基本使用 插件的基本配置很简单: <plugin> <groupId>org.apache.maven.plugins</groupId>

使用eclipse生成文档(javadoc)主要有三种方法:

使用eclipse生成文档(javadoc)主要有三种方法: 1,在项目列表中按右键,选择Export(导出),然后在Export(导出)对话框中选择java下的javadoc,提交到下一步. 在Javadoc Generation对话框中有两个地方要注意的: javadoc command:应该选择jdk的bin/javadoc.exe destination:为生成文档的保存路径,可自由选择. 按finish(完成)提交即可开始生成文档. 2,用菜单选择:File->Export(文件->

配置WCF同时支持WSDL和REST,swaggerwcf生成文档

配置WCF同时支持WSDL和REST,SwaggerWCF生成文档 VS创建一个WCF工程,通过NuGet添加SwaggerWcf 创建完成后通过 程序包管理控制台 pm>Install-Package SwaggerWcf 也可在 工具 -> NuGet包管理器 -> 管理解决方案的NuGet程序包 安装. 配置 首先对项目添加Global.asax文件,改动如下: protected void Application_Start(object sender, EventArgs e)

使用Aspose.Words生成文档

/// <summary> /// 生成设计变更工程联系函 /// </summary> /// <param name="DesignAlterGUID"></param> /// <returns></returns> private string GenerateDesignAlterDoc(string DesignAlterGUID) { string AlterCode, ProjectNameList

WebApi实现验证授权Token,WebApi生成文档等 - CSDN博客

原文:WebApi实现验证授权Token,WebApi生成文档等 - CSDN博客 [csharp] view plain copy print? using System; using System.Linq; using System.Web; using System.Web.Http; using System.Web.Security; namespace OtherApi.Auth { public class AuthFilterOutside : AuthorizeAttribu

使用文档生成器Doxygen为c#项目生成文档

文档生成器--Doxygen 一.简介 Doxygen是一种开源跨平台的,以类似JavaDoc(java开发环境自带的API文档生成工具)风格描述的文档系统,完全支持C.C++.Java.Objective-C和IDL语言,部分支持PHP.C#.注释的语法与Qt-Doc.KDoc和JavaDoc兼容.Doxgen可以从一套归档源文件(根据文件的形成规律和特点,保持文件之间的有机联系,区分不同价值,便于保管和利用的文件整理.)开始,生成HTML格式的在线类浏览器,或离线的LATEX.RTF参考手册