作者:荒野中得生存 | 来源:互联网 | 2023-05-18 01:34
http:www.itdaan.comimgs115121237e9ea84b730e1a98a1e0621e31f47f.jpeFreemarker+xml生成do
http://www.#.com/imgs/1/1/5/1/21/237e9ea84b730e1a98a1e0621e31f47f.jpe
Freemarker+xml生成docx
原理概述:word从2003版就支持xml格式,而freemarker是java封装的模板工具,两者结合也就是在xml中需要动态生成的部分调用freemarker的指令(类似于EL表达式),来生成我们需要的数据,再用流输出文件,就达到了写word的效果。
生成word的基本流程图如下:
1. 生成docx模板和xml模板
生成docx模板
按照项目需要生成固定格式的docx格式的模板。
为方便测试做了个简单的例子,docx模板的内容如下图:
生成xml模板
从docx模板中取出word/document.xml,由于docx属于zip格式,可以用winrar打开,如图:
除word文件夹外其它文件为基本配置文件,取出word/document.xml(存放word文件的文本内容)如下图:
需要把document.xml解压出来,修改里面需要从数据库导出的数据用freemarker的指令代替,例如${test} 同时可以用遍历函数
替换完成后相当于生成了xml模板
生成的Xml模板:
xml version="1.0" encoding="UTF-8" standalOne="yes"?>
<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:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/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" mc:Ignorable="w14 wp14">
<w:body>
<w:p w:rsidR="009175C2" w:rsidRDefault="005B5FB3" w:rsidP="005B5FB3">
<w:pPr>
<w:pStyle w:val="1"/>
<w:jc w:val="center"/>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
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:rPr>
<w:t>
这是一个测试Wordw:t>
w:r>
w:p>
<w:p w:rsidR="005B5FB3" w:rsidRDefault="005B5FB3" w:rsidP="005B5FB3">
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
w:rPr>
w:pPr>
w:p>
<w:p w:rsidR="005B5FB3" w:rsidRDefault="005B5FB3" w:rsidP="005B5FB3">
<w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
w:rPr>
w:pPr>
w:p>
<w:p w:rsidR="005B5FB3" w:rsidRDefault="005B5FB3" w:rsidP="005B5FB3">
<w:pPr>
<w:pStyle w:val="a3"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
w:numPr>
<w:ind w:firstLineChars="0"/>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
w:rPr>
w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
w:rPr>
<w:t>
${test}w:t>
w:r>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
w:rPr>
<w:t xml:space="preserve">
w:t>
w:r>
w:p>
<#list students as s>
<w:p w:rsidR="005B5FB3" w:rsidRDefault="005B5FB3" w:rsidP="005B5FB3">
<w:pPr>
<w:pStyle w:val="a3"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
w:numPr>
<w:ind w:firstLineChars="0"/>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
w:rPr>
w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
w:rPr>
<w:t>
${s}
w:t>
w:r>
w:p>
#list>
<w:sectPr w:rsidR="005B5FB3" w:rsidRPr="005B5FB3">
<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:docGrid w:type="lines" w:linePitch="312"/>
w:sectPr>
w:body>
w:document>
2. 利用freemarker填充数据并生成word文件
这里把数据库中的数据放到map中,把map和xml模板交给freemarker来生成(填充完数据)的xml具体实现方法如下:
package com.hannet.yigehui;
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;
import freemarker.template.TemplateException;
public class XmlToExcel {
private static XmlToExcel tplm = null;
private Configuration cfg = null;
private XmlToExcel() {
cfg = new Configuration();
try {
cfg.setClassForTemplateLoading(this.getClass(), "/template/");
} catch (Exception e) {
}
}
private static Template getTemplate(String name) throws IOException {
if(tplm == null) {
tplm = new XmlToExcel();
}
return tplm.cfg.getTemplate(name);
}
public static void process(String templatefile, Map param ,Writer out) throws IOException, TemplateException{
Template template=XmlToExcel.getTemplate(templatefile);
template.setOutputEncoding("UTF-8");
template.process(param, out);
if(out!=null){
out.close();
}
}
}
利用freemarker生成数据
调用freemarker中的process方法(上图中的方法)来填充数据。 例(用1中生成的xml为模板填充数据):
//xml的模板路径 template/test.xml String xmlTemplate = "test.xml"; //填充完数据的临时xml String xmlTemp = "d:\\temp.xml"; Writer w = new FileWriter(new File(xmlTemp)); //1.需要动态传入的数据 Map p = new HashMap(); List students = new ArrayList(); students.add("张三"); students.add("李四"); students.add("王二"); p.put("test", "测试一下是否成功"); p.put("students", students); //2.把map中的数据动态由freemarker传给xml XmlToExcel.process(xmlTemplate, p, w);
注:下文中会给出源码这里只是方便理解。
导出word文件
利用java的zipFile 和 ZipOutputStream 及zipFile.getInputStream() 来根据docx模板导出 (需要把word/document.xml文件替换成(填充完数据)的xml)具体操作流程如下:
推荐阅读
前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ...
[详细]
蜡笔小新 2023-12-11 12:31:00
本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ...
[详细]
蜡笔小新 2023-12-12 17:57:15
本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ...
[详细]
蜡笔小新 2023-12-13 16:31:57
本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ...
[详细]
蜡笔小新 2023-12-12 16:16:42
本文介绍了在使用Laravel和sqlsrv连接到SQL Server 2016时,如何在插入查询中使用输出子句,并返回所需的值。同时讨论了使用CreatedOn字段返回最近创建的行的解决方法以及使用Eloquent模型创建后,值正确插入数据库但没有返回uniqueidentifier字段的问题。最后给出了一个示例代码。 ...
[详细]
蜡笔小新 2023-12-11 10:09:09
本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ...
[详细]
蜡笔小新 2023-12-10 14:26:13
本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ...
[详细]
蜡笔小新 2023-12-13 13:42:30
本文详细介绍了MySQL表分区的创建、增加和删除方法,包括查看分区数据量和全库数据量的方法。欢迎大家阅读并给予点评。 ...
[详细]
蜡笔小新 2023-12-13 12:26:11
猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ...
[详细]
蜡笔小新 2023-12-13 12:04:03
本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ...
[详细]
蜡笔小新 2023-12-13 12:01:03
本文介绍了在C# WPF中实现自定义按钮的方法,包括使用图片作为按钮背景、自定义鼠标进入效果、自定义按压效果和自定义禁用效果。通过创建CustomButton.cs类和ButtonStyles.xaml资源文件,设计按钮的Style并添加所需的依赖属性,可以实现自定义按钮的效果。示例代码在ButtonStyles.xaml中给出。 ...
[详细]
蜡笔小新 2023-12-13 04:22:57
本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ...
[详细]
蜡笔小新 2023-12-11 17:54:55
本文介绍了如何使用PHP代码将表格导出为UTF8格式的Excel文件。首先,需要连接到数据库并获取表格的列名。然后,设置文件名和文件指针,并将内容写入文件。最后,设置响应头部,将文件作为附件下载。 ...
[详细]
蜡笔小新 2023-12-11 00:29:33
本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ...
[详细]
蜡笔小新 2023-12-10 19:22:56
本文介绍了在Ubuntu系统中清理残余配置文件和无用内容的方法,包括清理残余配置文件、清理下载缓存包、清理不再需要的包、清理无用的语言文件和清理无用的翻译内容。通过这些清理操作可以节省硬盘空间,提高系统的运行效率。 ...
[详细]
蜡笔小新 2023-12-09 10:04:56