1.maven导入需要的jar包
<!-- 引入freeMarker的依赖包. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
2.word模板另存为xml格式
3.写word导出工具类,改写模板目录,支持导出zip格式,根据目录得到图片的base64码
package com.zggk.framework.utils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import sun.misc.BASE64Encoder;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.zggk.framework.utils.word.WordHtmlGeneratorHelper;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* 报告生成工具类
*/
public class WordUtils {
private static Configuration configuration = null;
static {
configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
configuration.setClassForTemplateLoading(WordUtils.class,"/static/filetemp/");
}
private WordUtils() {
throw new AssertionError();
}
public static File createDoc( Map<?, ?> dataMap,String ftlFile,String name){
// String name = "xxx.doc";
File f = new File(name);
try {
Template Template = configuration.getTemplate(ftlFile,"UTF-8");
Writer w = new OutputStreamWriter(new FileOutputStream(f), "UTF-8");
Template.process(dataMap, w);
w.close();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
return f;
}
public void downloadWord( String process, HttpServletRequest request, HttpServletResponse response,String title,File file){
//响应头的设置
response.reset();
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
HttpSession session=request.getSession();
//设置压缩包的名字
String zipName=title+".zip";
//解决不同浏览器压缩包名字含有中文时乱码的问题
try {
zipName = new String(URLEncoder.encode(zipName, "UTF-8").getBytes(), "ISO-8859-1");
response.setHeader("Content-Disposition", "attachment;fileName=\"" + zipName + "\"");
} catch (Exception e) {
e.printStackTrace();
}
//设置压缩流:直接写入response,实现边压缩边下载
ZipOutputStream zipos = null;
try {
zipos = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
//zipos.setEncoding(System.getProperty("sun.jnu.encoding"));//设置文件名编码方式
zipos.setMethod(ZipOutputStream.DEFLATED); //设置压缩方法
} catch (Exception e) {
e.printStackTrace();
}
session.setAttribute(process, "97");
//循环将文件写入压缩流
DataOutputStream os = null;
try {
//添加ZipEntry,并ZipEntry中写入文件流
//这里,加上i是防止要下载的文件有重名的导致下载失败
zipos.putNextEntry(new ZipEntry(title+".doc"));
os = new DataOutputStream(zipos);
InputStream is = new FileInputStream(file);
byte[] b = new byte[100];
int length = 0;
session.setAttribute(process, "98");
while((length = is.read(b))!= -1){
os.write(b, 0, length);
}
session.setAttribute(process, "99");
is.close();
zipos.closeEntry();
} catch (IOException e) {
e.printStackTrace();
}
session.setAttribute(process, "100");
System.out.println("下载完成-----------------");
//关闭流
try {
os.flush();
os.close();
zipos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static File createDoc( Map<?, ?> dataMap,String ftlFile){
File f = new File("xxx.doc");
try {
Template Template = configuration.getTemplate(ftlFile);
Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
Template.process(dataMap, w);
w.close();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
return f;
}
public static String getImageBase(String src) {
if(src==null||src==""){
return "";
}
File file = new File(src);
if(!file.exists()) {
return "";
}
InputStream in = null;
byte[] data = null;
try {
in = new FileInputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
/**
* <p>描述:下载word文档的方法</p>
* @param request
* @param response
* @param title
* @param file
*/
public static void downloadReport(HttpServletRequest request, HttpServletResponse response, String title,File file,
String uid) {
HttpSession session=request.getSession();
InputStream fin = null;
OutputStream out = null;
try {
fin = new FileInputStream(file);
response.setCharacterEncoding("utf-8");
response.setContentType("application/msword");
// 设置浏览器以下载的方式处理该文件名
String fileName = title + ".doc";
response.setHeader("Content-Disposition", "attachment;filename="
.concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
out = response.getOutputStream();
byte[] buffer = new byte[512]; // 缓冲区
int len = -1;
// 通过循环将读入的Word文件的内容输出到浏览器中
while ((len = fin.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
if (fin != null) {
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (file != null) {
file.delete(); // 删除临时文件
}
// session.setAttribute(uid, "100");
}
}
// 根据目录得到图片的base64码
private String getImageBase64(String roadType, String zqCode, String itemOnlyNum) {
try {
String picName = roadType+zqCode+itemOnlyNum+".png";
InputStream in = new FileInputStream(PicUploadUtils.picPath+picName);
byte[] data = new byte[in.available()];
in.read(data);
in.close();
// 对字节数组Base64编码
byte[] encoder = new Base64().encodeBase64(data);
// 返回Base64编码过的字节数组字符串
return new String(encoder);
} catch (Exception e) {
return null;
}
}
}
4.导出controller层
@RequestMapping(value = "/download", produces = "text/html;charset=UTF-8")
public Object downloadReport(HttpServletRequest request, HttpServletResponse response) throws Exception {
try {
String uid = request.getParameter("uid");
String zqCode = request.getParameter("zqCode"); //政区编码
String roadType = request.getParameter("roadType"); //路线类型
String ids = request.getParameter("ids"); //条目id
String zqName = request.getParameter("zqName"); //条目id
String isEmpty = request.getParameter("isEmpty"); //是否导出空表的标识
HttpSession session=request.getSession();
session.setAttribute(uid, "0");
File file = printWordService.downloadReport(uid, session, request, response,zqCode,roadType,ids,zqName,isEmpty);
session.setAttribute(uid, "70"); HttpHeaders headers = new HttpHeaders();
String fileTitle = "公路养护管理规范化检查评分表";
if("H".equals(roadType)) {
fileTitle += "(高速公路)";
}else {
fileTitle += "(普通公路)";
}
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
String nowDate = formatter.format(new Date());
fileTitle += "-"+zqName+"-"+nowDate+".doc";
String fileName=new String(fileTitle.getBytes("UTF-8"),"iso-8859-1");//涓轰簡瑙e喅涓枃鍚嶇О涔辩爜闂
session.setAttribute(uid, "80");
headers.setContentDispositionFormData("attachment", fileName);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
session.setAttribute(uid, "100");
System.out.println("导出完成......");
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
5.导出下载模板service层,给map设置模板参数值
/**
* @Description 导出下载模板
* @author 巴菲增
* @Date 2020年9月4日 上午10:00:02
*/
public File downloadReport(String uid, HttpSession session, HttpServletRequest request,
HttpServletResponse response, String zqCode, String roadType, String ids, String zqName, String isEmpty) {
try {
Map<String,Object> dataMap = new HashMap<String, Object>();
List<PrintWord> list = new ArrayList<PrintWord>();
dataMap.put("imagesBase64String", "");
dataMap.put("imagesXmlHrefString", "");
if("H".equals(roadType)) {
dataMap.put("roadType", "高速公路");
list = getHighCheckData(zqCode,ids,isEmpty,dataMap); //得到高速公路检查记录
}else {
dataMap.put("roadType", "普通公路");
list = getCommonCheckData(zqCode,ids,isEmpty,dataMap); //得到普通公路检查记录
}
dataMap.put("zqName", zqName);
dataMap.put("lists", list);
String fileName = "template.xml";
if("true".equals(isEmpty)) { //选中导出空模板,不用填充检查时间、检查得分、检查截图
fileName = "empty.xml";
}
return WordUtils.createDoc(dataMap,fileName);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
6.模板文件,可以xml、ftl结尾都支持
<?xml version="1.0" encoding="utf-8"?>
<?mso-application progid="Word.Document"?>
<w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wsp="http://schemas.microsoft.com/office/word/2003/wordml/sp2" xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core" w:macrosPresent="no" w:embeddedObjPresent="no" w:ocxPresent="no" xml:space="preserve">
<w:ignoreSubtree w:val="http://schemas.microsoft.com/office/word/2003/wordml/sp2"/>
<o:DocumentProperties>
<o:Title>2010年全国干线公路养护管理</o:Title>
<o:Author>admin</o:Author>
<o:LastAuthor>1472052711@qq.com</o:LastAuthor>
<o:Revision>2</o:Revision>
<o:TotalTime>0</o:TotalTime>
<o:Created>2020-03-23T06:23:00Z</o:Created>
<o:LastSaved>2020-03-23T06:23:00Z</o:LastSaved>
<o:Pages>1</o:Pages>
<o:Words>74</o:Words>
<o:Characters>424</o:Characters>
<o:Company>Microsoft</o:Company>
<o:Lines>3</o:Lines>
<o:Paragraphs>1</o:Paragraphs>
<o:CharactersWithSpaces>497</o:CharactersWithSpaces>
<o:Version>16</o:Version>
</o:DocumentProperties>
<w:fonts>
<w:defaultFonts w:ascii="Times New Roman" w:fareast="宋体" w:h-ansi="Times New Roman" w:cs="Times New Roman"/>
<w:font w:name="Times New Roman">
<w:panose-1 w:val="02020603050405020304"/>
<w:charset w:val="00"/>
<w:family w:val="Roman"/>
<w:pitch w:val="variable"/>
<w:sig w:usb-0="E0002EFF" w:usb-1="C000785B" w:usb-2="00000009" w:usb-3="00000000" w:csb-0="000001FF" w:csb-1="00000000"/>
</w:font>
<w:font w:name="宋体">
<w:altName w:val="SimSun"/>
<w:panose-1 w:val="02010600030101010101"/>
<w:charset w:val="86"/>
<w:family w:val="auto"/>
<w:pitch w:val="variable"/>
<w:sig w:usb-0="00000003" w:usb-1="288F0000" w:usb-2="00000016" w:usb-3="00000000" w:csb-0="00040001" w:csb-1="00000000"/>
</w:font>
<w:font w:name="Cambria Math">
<w:panose-1 w:val="02040503050406030204"/>
<w:charset w:val="00"/>
<w:family w:val="Roman"/>
<w:pitch w:val="variable"/>
<w:sig w:usb-0="E00006FF" w:usb-1="420024FF" w:usb-2="02000000" w:usb-3="00000000" w:csb-0="0000019F" w:csb-1="00000000"/>
</w:font>
<w:font w:name="仿宋_GB2312">
<w:altName w:val="仿宋"/>
<w:charset w:val="86"/>
<w:family w:val="Modern"/>
<w:pitch w:val="default"/>
<w:sig w:usb-0="00000001" w:usb-1="080E0000" w:usb-2="00000010" w:usb-3="00000000" w:csb-0="00040000" w:csb-1="00000000"/>
</w:font>
<w:font w:name="@宋体">
<w:panose-1 w:val="02010600030101010101"/>
<w:charset w:val="86"/>
<w:family w:val="auto"/>
<w:pitch w:val="variable"/>
<w:sig w:usb-0="00000003" w:usb-1="288F0000" w:usb-2="00000016" w:usb-3="00000000" w:csb-0="00040001" w:csb-1="00000000"/>
</w:font>
<w:font w:name="@仿宋_GB2312">
<w:charset w:val="86"/>
<w:family w:val="Modern"/>
<w:pitch w:val="default"/>
<w:sig w:usb-0="00000001" w:usb-1="080E0000" w:usb-2="00000010" w:usb-3="00000000" w:csb-0="00040000" w:csb-1="00000000"/>
</w:font>
</w:fonts>
<w:lists>
<w:listDef w:listDefId="0">
<w:lsid w:val="41E40278"/>
<w:plt w:val="HybridMultilevel"/>
<w:tmpl w:val="FFFAAECC"/>
<w:lvl w:ilvl="0" w:tplc="0409000F">
<w:start w:val="1"/>
<w:lvlText w:val="%1."/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:tabs>
<w:tab w:val="list" w:pos="420"/>
</w:tabs>
<w:ind w:left="420" w:hanging="420"/>
</w:pPr>
</w:lvl>
<w:lvl w:ilvl="1" w:tplc="0AA6DFE2">
<w:start w:val="1"/>
<w:lvlText w:val="%2."/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:tabs>
<w:tab w:val="list" w:pos="840"/>
</w:tabs>
<w:ind w:left="840" w:hanging="420"/>
</w:pPr>
<w:rPr>
<w:color w:val="auto"/>
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="2" w:tplc="0409001B" w:tentative="on">
<w:start w:val="1"/>

本文介绍如何使用Freemarker和Java进行Word模板的创建与导出,包括maven依赖配置、模板生成工具类的实现、图片转Base64、Word文档下载及导出流程。

2939

被折叠的 条评论
为什么被折叠?



