RT,耗费了博主半个月的时间才挤出来的成果,在此记录下开发过程。
博主的另一篇文章改用mht模板导出了包含图片的word:
https://blog.csdn.net/u011099093/article/details/85318212
一、创建freemark模板
首先在web項目中指定目錄下創建一個HTML格式的freemarker模板:
导出html格式Word演示
Word导出演示
${basicShow!}
姓名
年龄
性别
<#if lists??>
<#list rows as lists>
${rows.name!}
${rows.age!}
${rows.gender!}
#list>
#if>
其中控制打開后展示為頁面視圖的是這一段:
Print
...
百度了好久都沒有百度到相關模板,就寫了個demo先使用html代碼生成一個word,再在word中修改格式,保存。
然後使用NodePad打開保存后的doc文檔分析其中的結構才拼凑成一個格式比較像樣的模板。
控制頁邊距的是以下這一段:
使用${param!}引入參數,使用<#if lists??><#list rows as lists>#list>#if>遍歷多條數據插入到模板中;
二、导入数据到模板并生成word
@ResponseBody
@RequestMapping("/exportWord")
public Map exportWord(HttpServletRequest request){
try {
//遍历獲取所有參數
Enumeration enu = request.getParameterNames();
String paraName = null;
Map parameters = new HashMap<>();
while (enu.hasMoreElements()) {
paraName = enu.nextElement();
parameters.put(paraName, request.getParameter(paraName));
}
//準備一段假數據
Map map = new HashMap<>();
map.put("basicShow", "這裏展示一段文字。。。啦啦啦");
List list = new ArrayList<>();
list.add(new User() {{
setAge(18);
setGender("男");
setName("趙康");
}});
list.add(new User() {{
setAge(34);
setGender("男");
setName("劉天");
}});
list.add(new User() {{
setAge(23);
setGender("女");
setName("李逵");
}});
map.put("lists", list);
String path = request.getRealPath("/");//獲取項目的根目錄
ServletContext context = request.getServletContext();
String filepath = createDoc(path, context, map, "wordOfHtml.ftl", "测试word文档.doc");
Map resultMap = new HashMap<>();
resultMap.put("filepath", filepath);
return resultMap;
}catch(Exception e){
e.printStackTrace();
}
return null;
}
private String createDoc(String path, ServletContext context, Map data, String templateName, String docName) {
long startTime=System.currentTimeMillis();
System.out.println("生成word开始。。。");
Configuration configurationc=new Configuration();
//设置模板编码格式
configurationc.setDefaultEncoding("utf-8");
//设置模板存放的路径
configurationc.setServletContextForTemplateLoading(context,"freemarkTemplate");
Template template=null;
String filepath=null;
String htmlpath=null;
try{
//获取模板设置编码类型
template=configurationc.getTemplate(templateName,"UTF-8");
//设置生成word文件的存放路径
filepath= path+"export"+File.separator;//+"test.doc";
File file=new File(filepath);
if(!file.exists()){
// file.createNewFile();
file.mkdirs();
}
filepath+=docName;
Writer bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filepath),"utf-8"));
// BufferedWriter bw=new BufferedWriter(new FileWriter(filepath));
//替换模板中的占位符并输出
template.process(data,bw, ObjectWrapper.BEANS_WRAPPER);
return filepath;
}catch (Exception e){
e.printStackTrace();
}finally {
long end=System.currentTimeMillis();
System.out.println("用时:"+(end-startTime)/1000+"秒;");
System.out.println("生成word结束,开始下载。。。");
}
return null;
}
这里为了测试,我直接造的假数据放到Map中,替换模板中对应的参数;
三、导出word
@ResponseBody
@RequestMapping("/downloadWord")
public void downloadWord(HttpServletResponse response,String filepath){
OutputStream os=null;
FileInputStream inputStream=null;
System.out.println("开始下载。。。");
try{
File file=new File(filepath);
String filename=new String(file.getName().getBytes("GB2312"),"ISO8859-1");
//设置输出文件类型为 word.doc
response.setContentType("application/msword");
//设置文件名
response.setHeader("Content-Disposition","attachment;filename="+filename);
String len=String.valueOf(file.length());
response.setHeader("Content-length",len);
os=response.getOutputStream();
inputStream=new FileInputStream(file);
byte[] bytes=new byte[1024];
int i;
while((i=inputStream.read(bytes))!=-1){
os.write(bytes,0,i);
}
os.flush();
boolean b=file.delete();
System.out.println(b+"----------");
}catch(Exception e){
e.printStackTrace();
}
finally {
try {
if (inputStream != null) {
inputStream.close();
}
if(os!=null){
os.close();
}
}catch(Exception e){
e.printStackTrace();
}
System.out.println("下载完成。。。");
}
}
前台js:
$.ajax({
url: _ctx+'/report/common/exportWord',
data: {},
type: 'post',
dataType: 'json',
success: function (obj) {
var filepath=obj.filepath;
console.info(filepath)
if(filepath!=null){
var encode2=encodeURIComponent(filepath);
console.info(encode2)
console.log(_ctx+'/report/common/downloadWord?'+(new Date().getTime())+"&filepath="+encode2)
window.location.href=_ctx+'/report/common/downloadWord?'+(new Date().getTime())+"&filepath="+encode2;
}else{
alert("下载word失败!");
}
}
})
效果:
使用nodepad打开word,发现其实格式还是html:
所以如果需要什么样式可以直接在word中修改,然后保存,使用记事本打开就可以看到对应的样式,希望对各位小伙伴有所帮助!
-------------------------------------------------华丽的分割线-----------------------------------------------------
(原创文档,转载请注明出处。)