java最简单的根据.xml或.ftl数据导出成word
废话不多说,直接开搞
1.首先要把要转成的word文档另存为word2003格式的.xml;(打开word文档,然后找到另存为,出现下图保存即可,也可以转换成.ftl格式(就是讲xml后缀改成.ftl格式)方式一样,这里只说一种)
2.保存完xml文件后(最好用Hbuilder,notePad++,ws等软件格式化,这样容易看的清晰),进行动态修改数据,如下是我修改的
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?mso-application progid="Word.Document"?>
<pkg:package xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage">
<pkg:part pkg:name="/_rels/.rels" pkg:contentType="application/vnd.openxmlformats-package.relationships+xml">
<pkg:xmlData>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml" />
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml" />
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml" />
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml" />
</Relationships>
</pkg:xmlData>
</pkg:part>
<pkg:part pkg:name="/word/_rels/document.xml.rels" pkg:contentType="application/vnd.openxmlformats-package.relationships+xml">
<pkg:xmlData>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml" />
<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml" Target="../customXml/item1.xml" />
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml" />
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml" />
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml" />
</Relationships>
</pkg:xmlData>
</pkg:part>
<pkg:part pkg:name="/word/document.xml" pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml">
<pkg:xmlData>
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:wpsCustomData="http://www.wps.cn/officeDocument/2013/wpsCustomData" mc:Ignorable="w14 w15 wp14">
<w:body>
<w:p>
<w:pPr>
<w:jc w:val="center" />
<w:rPr>
<w:rFonts w:hint="eastAsia" />
<w:b/>
<w:bCs/>
<w:sz w:val="28" />
<w:szCs w:val="28" />
<w:lang w:val="en-US" w:eastAsia="zh-CN" /></w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia" />
<w:b/>
<w:bCs/>
<w:sz w:val="28" />
<w:szCs w:val="28" />
<w:lang w:val="en-US" w:eastAsia="zh-CN" /></w:rPr>
<w:t>${title}</w:t>
</w:r>
</w:p>
<w:tbl>
<w:tblPr>
<w:tblStyle w:val="4" />
<w:tblW w:w="8522" 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:left w:w="108" w:type="dxa" />
<w:right w:w="108" w:type="dxa" /></w:tblCellMar>
</w:tblPr>
<w:tblGrid>
<w:gridCol w:w="2130" />
<w:gridCol w:w="2130" />
<w:gridCol w:w="2131" />
<w:gridCol w:w="2131" /></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:tblPrEx>
<#list tableHeader as header>
<w:tc>
<w:tcPr>
<w:tcW w:w="2130" w:type="dxa" />
<w:vAlign w:val="top" />
</w:tcPr>
<w:p>
<w:pPr>
<w:jc w:val="both" />
<w:rPr>
<w:rFonts w:hint="eastAsia" />
<w:b/>
<w:bCs/>
<w:sz w:val="28" />
<w:szCs w:val="28" />
<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:b/>
<w:bCs/>
<w:sz w:val="28" />
<w:szCs w:val="28" />
<w:vertAlign w:val="baseline" />
<w:lang w:val="en-US" w:eastAsia="zh-CN" />
</w:rPr>
<w:t><#if header ? exists>${header}</#if></w:t>
</w:r>
</w:p>
</w:tc>
</#list>
</w:tr>
<#list tableContents as tc>
<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:left w:w="108" w:type="dxa" />
<w:right w:w="108" w:type="dxa" />
</w:tblCellMar>
</w:tblPrEx>
<w:tc>
<w:tcPr>
<w:tcW w:w="2130" w:type="dxa" />
<w:vAlign w:val="top" />
</w:tcPr>
<w:p>
<w:pPr>
<w:jc w:val="both" />
<w:rPr>
<w:rFonts w:hint="eastAsia" />
<w:b/>
<w:bCs/>
<w:sz w:val="28" />
<w:szCs w:val="28" />
<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:b/>
<w:bCs/>
<w:sz w:val="28" />
<w:szCs w:val="28" />
<w:vertAlign w:val="baseline" />
<w:lang w:val="en-US" w:eastAsia="zh-CN" />
</w:rPr>
<w:t><#if tc[0] ? exists>${tc[0]}</#if></w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2130" w:type="dxa" />
<w:vAlign w:val="top" />
</w:tcPr>
<w:p>
<w:pPr>
<w:jc w:val="both" />
<w:rPr>
<w:rFonts w:hint="eastAsia" />
<w:b/>
<w:bCs/>
<w:sz w:val="28" />
<w:szCs w:val="28" />
<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:b/>
<w:bCs/>
<w:sz w:val="28" />
<w:szCs w:val="28" />
<w:vertAlign w:val="baseline" />
<w:lang w:val="en-US" w:eastAsia="zh-CN" />
</w:rPr>
<w:t><#if tc[1] ? exists>${tc[1]}</#if></w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2131" w:type="dxa" />
<w:vAlign w:val="top" />
</w:tcPr>
<w:p>
<w:pPr>
<w:jc w:val="both" />
<w:rPr>
<w:rFonts w:hint="eastAsia" />
<w:b/>
<w:bCs/>
<w:sz w:val="28" />
<w:szCs w:val="28" />
<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:b/>
<w:bCs/>
<w:sz w:val="28" />
<w:szCs w:val="28" />
<w:vertAlign w:val="baseline" />
<w:lang w:val="en-US" w:eastAsia="zh-CN" />
</w:rPr>
<w:t><#if tc[2] ? exists>${tc[2]}</#if></w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2131" w:type="dxa" />
<w:vAlign w:val="top" />
</w:tcPr>
<w:p>
<w:pPr>
<w:jc w:val="both" />
<w:rPr>
<w:rFonts w:hint="eastAsia" />
<w:b/>
<w:bCs/>
<w:sz w:val="28" />
<w:szCs w:val="28" />
<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:b/>
<w:bCs/>
<w:sz w:val="28" />
<w:szCs w:val="28" />
<w:vertAlign w:val="baseline" />
<w:lang w:val="en-US" w:eastAsia="zh-CN" />
</w:rPr>
<w:t><#if tc[3] ? exists>${tc[3]}</#if></w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
</#list>
</w:tbl>
<w:p>
<w:pPr>
<w:jc w:val="center" />
<w:rPr>
<w:rFonts w:hint="eastAsia" />
<w:b/>
<w:bCs/>
<w:sz w:val="28" />
<w:szCs w:val="28" />
<w:lang w:val="en-US" w:eastAsia="zh-CN" /></w:rPr>
</w:pPr>
</w:p>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia" w:ascii="Calibri" w:hAnsi="Calibri" w:eastAsia="宋体" w:cs="Times New Roman" />
<w:b/>
<w:bCs/>
<w:kern w:val="2" />
<w:sz w:val="28" />
<w:szCs w:val="28" />
<w:lang w:val="en-US" w:eastAsia="zh-CN" w:bidi="ar-SA" /></w:rPr>
</w:pPr>
</w:p>
<w:p>
<w:pPr>
<w:tabs>
<w:tab w:val="left" w:pos="6298" /></w:tabs>
<w:jc w:val="left" />
<w:rPr>
<w:rFonts w:hint="eastAsia" />
<w:lang w:val="en-US" w:eastAsia="zh-CN" /></w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia" w:cs="Times New Roman" />
<w:b/>
<w:bCs/>
<w:kern w:val="2" />
<w:sz w:val="28" />
<w:szCs w:val="28" />
<w:lang w:val="en-US" w:eastAsia="zh-CN" w:bidi="ar-SA" /></w:rPr>
<w:tab/></w:r>
<w:bookmarkStart w:id="0" w:name="_GoBack" />
<w:bookmarkEnd w:id="0" /></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="720" w:num="1" />
<w:docGrid w:type="lines" w:linePitch="312" w:charSpace="0" /></w:sectPr>
</w:body>
</w:document>
</pkg:xmlData>
</pkg:part>
</pkg:package>
这个只是简单地实现了表格的模板,其中好多是没用的偷个懒就直接弄上了,其实很简单,最主要是理解<w:tc></w:tc>是代表的一个格子;<w:tr></w:tr>代表的是完整的一行,还有最重要的是要把传过来的值判空利用<#if ></#if>就可以,明白了这些剩下的就是循环了。下面是自己实现的简单地demo
package com.qianyu.production.test;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.commons.net.util.Base64;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by G400 on 2018/10/30.
* 功能:根据模板生成word表格
* 作者:
*/
public class CreateWordTest {
public static void main(String[] args) {
// 模板文件路径:
String templetFilePath = "D:/Rj/workspace/text.xml";
// 目标文件存放路径
String targetFilePath = "D:/Rj/workspace/text.doc";
try {
// 将xml模板转换为后缀为doc文件,本质仍是属于xml
xml2XmlDoc(getData(),templetFilePath,targetFilePath);
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
public static Map<String, Object> getData() {
Map<String, Object> dataMap = new HashMap<String, Object>();
List<String[]> tableContents = new ArrayList<String[]>();
String[] tableHeader = new String[]{"序号", "标题", "功能", "备注"};
String[] tableContent1 = new String[]{"序号1的内容", "标题1的内容", "功能1的内容", "备注1的内容"};
String[] tableContent2 = new String[]{"序号2的内容", "标题2的内容", "功能2的内容", "备注3的内容"};
String[] tableContent3 = new String[]{"序号3的内容", "标题3的内容", "功能2的内容", "备注3的内容"};
dataMap.put("title", "根据模板生成word表格");
tableContents.add(tableContent1);
tableContents.add(tableContent2);
tableContents.add(tableContent3);
dataMap.put("tableHeader", tableHeader);
dataMap.put("tableContents", tableContents);
return dataMap;
}
/**
* 将xml模板转换为后缀为doc文件,本质仍是属于xml
*
* @param dataMap 需要填充到模板的数据
* @param templetFilePath 模板文件路径
* @param targetFilePath 目标文件保存路径
* @throws IOException
* @throws TemplateException
*/
public static void xml2XmlDoc(Map<String, Object> dataMap, String templetFilePath, String targetFilePath) throws IOException, TemplateException {
// 将模板文件路径拆分为文件夹路径和文件名称
String tempLetDir = templetFilePath.substring(0, templetFilePath.lastIndexOf("/"));
// 注意:templetFilePath.lastIndexOf("/")中,有的文件分隔符为:\ 要注意文件路径的分隔符
String templetName = templetFilePath.substring(templetFilePath.lastIndexOf("/") + 1);
// 将目标文件保存路径拆分为文件夹路径和文件名称
String targetDir = targetFilePath.substring(0, targetFilePath.lastIndexOf("/"));
String targetName = targetFilePath.substring(targetFilePath.lastIndexOf("/") + 1);
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
// 如果目标文件目录不存在,则需要创建
File file = new File(targetDir);
if (!file.exists()) {
file.mkdirs();
}
// 加载模板数据(从文件路径中获取文件,其他方式,可百度查找)
configuration.setDirectoryForTemplateLoading(new File(tempLetDir));
// 获取模板实例
Template template = configuration.getTemplate(templetName);
File outFile = new File(targetDir + File.separator + targetName);
//将模板和数据模型合并生成文件
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8"));
//生成文件
template.process(dataMap, out);
out.flush();
out.close();
}
/**
* 将图片转换成Base64编码 (优化:在web工程下,可通过工程路径获取流的方式获取图片)
*
* @param imgFilePath 图片路径
* @return
* @throws IOException
*/
public static String getImgStr(String imgFilePath) throws IOException {
//将图片文件转化为字节数组字符串,并对其进行Base64编码处理
InputStream in = null;
byte[] data = null;
//读取图片字节数组
in = new FileInputStream(imgFilePath);
data = new byte[in.available()];
in.read(data);
in.close();
return new String(Base64.encodeBase64(data));
}
}
生成的word如下图
还有这个只是简单地表格,如果合并单元格需要在tr加入标签:
具体合并方法:<#if imageList_index == 0><w:vmerge w:val=“restart”/><#else><w:vmerge/></#if>
开始合并的行:<w:vmerge w:val=“restart”/>
需要合并的行:<w:vmerge/>
或者表格里面有图片的需要用上面的方法将图片转换成Base64编码,写的可能有点乱,希望能对小伙伴们有所帮助
参考借鉴[https://blog.csdn.net/abc231218/article/details/80512463]