您的位置:首页 > 数据库

从数据库中取出数据,使用freemarker生成word文档

2016-04-29 10:08 681 查看
这个星期做数据字典功能,有一项任务就是将数据库中的每个表的字段导出,生成word文档,在综合比较网上各种技术之后,参照csdn上骆豪的博客完成了任务。

骆昊的链接:http://blog.csdn.net/jackfrued/article/details/39449021

首先打开word文档,建立自己所需要的模板,然后将word保存为XML的格式,这里可能出现的一个问题就是需要填入的内容放上${}占位符的时候可能会出现字符分离的情况,所以建议先将需要用${}占位符的地方用中文写在word里然后保存为XML的格式,再打开XML对需要用${}占位符的地方进行替换,这样就避免了字符分离的情况。推荐使用一个软件,foxe,这个软件编辑XML很方便,如下图所示,按F8可以对XML进行格式化,然后再对XML进行编辑。



将需要用${}占位符输出的字段替换好之后,将文件另存为ftl格式即可。

将freemarker的jar包导入lib之后,开始编写代码。

因为项目需要,我是需要将数据库中的表的和表的字段都读取出来,所以可以使用两层list进行封装。

首先,使用一个Java bean封装,代码如图所示
import java.util.List;

public class allTables {
String title;
String commont;
int count;
List<CommonDictionary> commonDictionaries;

public String getCommont() {
return commont;
}

public void setCommont(String commont) {
this.commont = commont;
}

public int getCount() {
return count;
}

public void setCount(int count) {
this.count = count;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public List<CommonDictionary> getCommonDictionaries() {
return commonDictionaries;
}

public void setCommonDictionaries(List<CommonDictionary> commonDictionaries) {
this.commonDictionaries = commonDictionaries;
}
}


这个Javabean是对表进行进行封装,然后再使用一个Javabean对表的属性进行封装,如图所示:

package cn.changhong.dictionary.domain;

import java.util.Date;

public class CommonDictionary {
String cId;
String cName;
String cCommont;
String cDataType;
String primaryKey;
String createUser;
Date createTime;
String updateUser;
Date updateTime;
String cLength;
int num;
String isNull;

public String getIsNull() {
return isNull;
}

public void setIsNull(String isNull) {
this.isNull = isNull;
}

public int getNum() {
return num;
}

public void setNum(int num) {
this.num = num;
}

public Date getCreateTime() {
return createTime;
}

public void setCreateTime(Date createTime) {
this.createTime = createTime;
}

public Date getUpdateTime() {
return updateTime;
}

public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}

public String getcId() {
return cId;
}

public void setcId(String cId) {
this.cId = cId;
}

public String getcName() {
return cName;
}

public void setcName(String cName) {
this.cName = cName;
}

public String getcCommont() {
return cCommont;
}

public void setcCommont(String cCommont) {
this.cCommont = cCommont;
}

public String getcDataType() {
return cDataType;
}

public void setcDataType(String cDataType) {
this.cDataType = cDataType;
}

public String getPrimaryKey() {
return primaryKey;
}

public void setPrimaryKey(String primaryKey) {
this.primaryKey = primaryKey;
}

public String getCreateUser() {
return createUser;
}

public void setCreateUser(String createUser) {
this.createUser = createUser;
}

public String getUpdateUser() {
return updateUser;
}

public void setUpdateUser(String updateUser) {
this.updateUser = updateUser;
}

public String getcLength() {
return cLength;
}

public void setcLength(String cLength) {
this.cLength = cLength;
}

}


项目的结构如下图:



在WordDownController层将数据封装好。

代码如下:
package cn.changhong.dictionary.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import cn.changhong.dictionary.domain.CommonDictionary;
import cn.changhong.dictionary.domain.DcTable;
import cn.changhong.dictionary.domain.allTables;
import cn.changhong.dictionary.service.CommonDictionaryService;
import cn.changhong.dictionary.util.WordGenerator;
import cn.changhong.system.util.BaseDaoSupport;

@Controller
@RequestMapping("/word")
public class WordDownController extends BaseDaoSupport {

@Autowired
CommonDictionaryService cs;

@RequestMapping("/down")
public void download(HttpServletRequest req, HttpServletResponse resp) throws IOException {

req.setCharacterEncoding("utf-8");
Map<String, Object> map = new HashMap<String, Object>();
/*
* map.put("title","哈哈"); map.put("num", 1); map.put("cName",2);
* map.put("cCommont", 3); map.put("cDataType",4); map.put("cLength",
* 5); map.put("primaryKey", 6);
*/

try {
List<allTables> aTables = new ArrayList<allTables>();
List<DcTable> tables = cs.qureyalltables();//选出所有的表名
int j=1;
for (DcTable table : tables) {
int i = 1;
List<CommonDictionary> colums = cs.querycolumnbytable(table.gettName());//选出每个表的属性
for (CommonDictionary column : colums) {//增加序号
column.setNum(i);
if(column.getPrimaryKey().equals("0")){
column.setPrimaryKey("✘");
}else if(column.getPrimaryKey().equals("1")){
column.setPrimaryKey("✔");
}
if(column.getIsNull().equals("0")){
column.setIsNull("✔");
}else if(column.getIsNull().equals("1")){
column.setIsNull("✘");
}

i++;
}

allTables allTables = new allTables();
allTables.setTitle(table.gettName());
allTables.setCount(j);
allTables.setCommont(table.gettCommont());
allTables.setCommonDictionaries(colums);
aTables.add(allTables);//放入list里面
j++;
}
map.put("listmap", aTables);//放入map里面
} catch (Exception e) {
// TODO: handle exception
}

/*
* 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, "resume");
fin = new FileInputStream(file);

resp.setCharacterEncoding("utf-8");
resp.setContentType("application/msword");
// 设置浏览器以下载的方式处理该文件默认名为resume.doc
resp.addHeader("Content-Disposition", "attachment;filename=resume.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(); // 删除临时文件
}

}
}


将数据封装放到list里面,然后放入map.

在ftl 利用<#list>标签进行两次循环即可取出数据。

ftl的代码片段如下:
<w:body>
<#list listmap as maps>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
<w:bookmarkStart w:id="0" w:name="_GoBack"/>
<w:bookmarkEnd w:id="0"/>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<w:t>表名:${maps.title}</w:t>
</w:r>
</w:p>
<w:tbl>
<w:tblPr>
<w:tblStyle w:val="4"/>
<w:tblW w:w="7304" w:type="dxa"/>
<w:tblInd w:w="0" w:type="dxa"/>
<w:tblBorders>
<w:top w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:left w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:bottom w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:right w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:insideH w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:insideV w:val="single" w:color="auto" w:sz="4" w:space="0"/>
</w:tblBorders>
<w:tblLayout w:type="fixed"/>
<w:tblCellMar>
<w:top w:w="0" w:type="dxa"/>
<w:left w:w="108" w:type="dxa"/>
<w:bottom w:w="0" w:type="dxa"/>
<w:right w:w="108" w:type="dxa"/>
</w:tblCellMar>
</w:tblPr>
<w:tblGrid>
<w:gridCol w:w="1217"/>
<w:gridCol w:w="1217"/>
<w:gridCol w:w="1217"/>
<w:gridCol w:w="1217"/>
<w:gridCol w:w="1218"/>
<w:gridCol w:w="1218"/>
</w:tblGrid>
<w:tr>
<w:tblPrEx>
<w:tblBorders>
<w:top w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:left w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:bottom w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:right w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:insideH w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:insideV w:val="single" w:color="auto" w:sz="4" w:space="0"/>
</w:tblBorders>
<w:tblLayout w:type="fixed"/>
<w:tblCellMar>
<w:top w:w="0" w:type="dxa"/>
<w:left w:w="108" w:type="dxa"/>
<w:bottom w:w="0" w:type="dxa"/>
<w:right w:w="108" w:type="dxa"/>
</w:tblCellMar>
</w:tblPrEx>
<w:tc>
<w:tcPr>
<w:tcW w:w="1217" w:type="dxa"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<w:t>序号</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1217" w:type="dxa"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<w:t>字段</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1217" w:type="dxa"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<w:t>备注</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1217" w:type="dxa"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<w:t>数据类型</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1218" w:type="dxa"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<w:t>长度</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1218" w:type="dxa"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<w:t>是否主键</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>

<#list maps.commonDictionaries as commonDictionary>

<w:tr>
<w:tblPrEx>
<w:tblBorders>
<w:top w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:left w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:bottom w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:right w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:insideH w:val="single" w:color="auto" w:sz="4" w:space="0"/>
<w:insideV w:val="single" w:color="auto" w:sz="4" w:space="0"/>
</w:tblBorders>
<w:tblLayout w:type="fixed"/>
<w:tblCellMar>
<w:top w:w="0" w:type="dxa"/>
<w:left w:w="108" w:type="dxa"/>
<w:bottom w:w="0" w:type="dxa"/>
<w:right w:w="108" w:type="dxa"/>
</w:tblCellMar>
</w:tblPrEx>
<w:tc>
<w:tcPr>
<w:tcW w:w="1217" w:type="dxa"/>
<w:textDirection w:val="lrTb"/>
<w:vAlign w:val="top"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<w:t>${commonDictionary.num}</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1217" w:type="dxa"/>
<w:textDirection w:val="lrTb"/>
<w:vAlign w:val="top"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<w:t>${commonDictionary.cName}</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1217" w:type="dxa"/>
<w:textDirection w:val="lrTb"/>
<w:vAlign w:val="top"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<w:t>${commonDictionary.cCommont}</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1217" w:type="dxa"/>
<w:textDirection w:val="lrTb"/>
<w:vAlign w:val="top"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<w:t>${commonDictionary.cDataType}</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1218" w:type="dxa"/>
<w:textDirection w:val="lrTb"/>
<w:vAlign w:val="top"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<w:t>${commonDictionary.cLength}</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1218" w:type="dxa"/>
<w:textDirection w:val="lrTb"/>
<w:vAlign w:val="top"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<w:t>${commonDictionary.primaryKey}</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>

</#list>

</w:tbl>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
</w:p>
<w:sectPr>
<w:pgSz w:w="11906" w:h="16838"/>
<w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0"/>
<w:cols w:space="425" w:num="1"/>
<w:docGrid w:type="lines" w:linePitch="312" w:charSpace="0"/>
</w:sectPr>

</#list>

</w:body>
推荐使用foxe进行编辑,第一层list标签放入 <w:body>下
<w:body>
<#list listmap as maps>


第二层list标签根据需要放到<w:tr>上这样就可以循环输出各个表的结构了,最后找到闭合标签放入</#list>,这样就可以实现循环了,注意:<w:tr>的闭合标签。
<#list maps.commonDictionaries as commonDictionary>

<w:tr>
文档输出入下图所示:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: