java利用Freemark生成docx格式附件

 1、 首先去官网下载freemarker对应的jar包,我这边用的是这个架包 -- freemarker-2.3.18.jar。

 2、 然后新建一个document.docx 的world文件,新建后把要替换的地方放占位符如“${userName}”。

 3、用你本地安装的解压工具打开压缩包(.docx可以看作是个压缩包),在word目录下,取出document.xml文件。

 4、用notepad++打开,并且格式化xml,然后你的需求编辑(至于你要编辑成什么样得格式,网上可以找到 )。

 5、把你本地的document.docx和解压取出来编辑好的document.xml文件,相互替换后缀

    (PS:把document.docx替换为document.xml,把document.xml替换为document.docx)。

 不说那么多了上Code了.。

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

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

import org.springframework.web.bind.annotation.RequestMapping;

import com.sf.core.annotion.Action;
import com.sf.platform.model.system.SysAuditModelType;

import freemarker.template.Template;
import freemarker.template.TemplateException;


public class Test {
public static void main(String[] args) throws IOException, TemplateException { 
Map<String,Object> agnMap = new HashMap<String,Object>();
agnMap.put("userName","duandingfeng");
process("E:\\test\\document.docx", agnMap,"E:\\test\\document.xml");

}

/**
* @param templatefile
* 模板文件
* @param param
* 需要填充的内容
* @param out
* 填充完成输出的文件
* @throws IOException 
* @throws TemplateException 
*/
public static String process(String templatefile, Map<String,Object> param,
String docxTemplate) throws IOException, TemplateException {
FileOutputStream fos = null;
String templFilePath = null;
// 获取模板
try {
String zipFileName = buildRandomFilePath("E:\\test\\2019");
String dirName = zipFileName.substring(0,
zipFileName.lastIndexOf(File.separator));
File dir = new File(dirName);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(zipFileName);
fos = new FileOutputStream(file);
Writer out = new BufferedWriter(
new OutputStreamWriter(fos, "UTF-8"));// 生产文件输出流
Template template = XmlToDocx.getTemplate(templatefile);
template.setOutputEncoding("UTF-8");
// 合并数据
template.process(param, out);
out.flush();
templFilePath = zipFileName;//这里是生产io文件,如果生成.docx文件,把对应的文件名后缀改成.docx即可,如:E:\\test\\2019\\test.docx
outDocx(file, docxTemplate, templFilePath);
} catch (IOException e) {
throw e; 
} catch (TemplateException e) {
throw e;
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return templFilePath;
}

public static void outDocx(File documentFile, String docxTemplate,
String toFilePath) {
ZipFile zipFile = null;
ZipOutputStream zipout = null;
InputStream in = null;
FileOutputStream out = null;
InputStream is = null;
try {
File docxFile = new File(docxTemplate);
zipFile = new ZipFile(docxFile);
Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();
out = new FileOutputStream(toFilePath);
zipout = new ZipOutputStream(out);
int len = -1;
byte[] buffer = new byte[1024];
while (zipEntrys.hasMoreElements()) {
ZipEntry next = zipEntrys.nextElement();
is = zipFile.getInputStream(next);
// 把输入流的文件传到输出流中 如果是word/document.xml由我们输入
zipout.putNextEntry(new ZipEntry(next.toString()));
if ("word/document.xml".equals(next.toString())) {
in = new FileInputStream(documentFile);
while ((len = in.read(buffer)) != -1) {
zipout.write(buffer, 0, len);
}
} else {
while ((len = is.read(buffer)) != -1) {
zipout.write(buffer, 0, len);
}

}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
XmlToDocx.close(zipout, in, out, is, zipFile);
}
}

/**
* 附件下载
* @param request
* @param response
* @throws IOException 
* @throws UnsupportedEncodingException 
*/
@RequestMapping("fileDownload")
@Action(description="附件下载",ownermodel=SysAuditModelType.SYSTEM_SETTING,exectype="管理日志")
public void fileDownload(HttpServletRequest request, HttpServletResponse response) throws Exception {
downLoadFile(response, new File("E:\\test\\2019\\0088514422227330436402.io"), "全日制合同");
}

/**
* 下载文件。
* @param response
* @param fullPath    文件的全路径
* @param fileName    文件名称。
* @throws IOException
*/
public static void downLoadFile(HttpServletResponse response, File file, String fileName) throws IOException {
try {
downLoadFile(response, new FileInputStream(file), fileName);
} catch (Exception cae) {
response.getOutputStream().write("<script>$.ligerDialog.warn(\"系统处理文件发生异常!\");</script>".getBytes("UTF-8"));
}
}


/**
* 下载文件。
* @param response
* @param fullPath    文件的全路径
* @param fileName    文件名称。
* @throws IOException
*/
public static void downLoadFile(HttpServletResponse response, InputStream in, String fileName) throws Exception {
OutputStream outputStream = response.getOutputStream();
if(null == fileName || "".equals(fileName)){
fileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
}
try {
//读取文件
response.setContentType("APPLICATION/OCTET-STREAM");
String filedisplay = URLEncoder.encode(fileName, "UTF-8");
response.addHeader("Content-Disposition", "attachment;filename="+ filedisplay);
response.setHeader("Cache-Control", "must-revalidate");
//开始写入流
byte[] b = new byte[1024];
int i = 0;
while ((i = in.read(b)) > 0) {
outputStream.write(b, 0, i);
}
outputStream.flush();
} finally {
if (in != null) {
in.close();
in = null;
outputStream.close();
outputStream = null;
response.flushBuffer();
}
}
}

/**
* 构造一个随机文件路径
* @param dir 目录
* @param filenameOrType 文件名称或文件类型,当为[文件名称]时必须带后缀(文件类型),否则将视为文件类型处理
* @return
*/
public static String buildRandomFilePath(String dir){
StringBuilder path = new StringBuilder(dir);
if(!dir.endsWith(File.separator)) {
path.append(File.separator);
}
String filenameOrType = ".io";
return path.append(String.valueOf(Math.random()).replace(".", "")).append(filenameOrType).toString();
}
}

 

 

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Enumeration;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;


public class XmlToDocx {
private static final Logger logger = LoggerFactory
.getLogger(XmlToDocx.class);
private static XmlToDocx tplm = null;
private Configuration cfg = null;

private XmlToDocx(String filepath) {
cfg = new Configuration();
try {
cfg.setDirectoryForTemplateLoading(new File(filepath));
// 注册tmlplate的load路径
// cfg.setClassForTemplateLoading(this.getClass(), "/");
cfg.setObjectWrapper(new DefaultObjectWrapper());// 指定生产模板的方式
cfg.setDefaultEncoding("utf-8");// 设置模板读取的编码方式,用于处理乱码
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}

public static Template getTemplate(String name) throws IOException {
if (tplm == null) {
tplm = new XmlToDocx(name.substring(0,
name.lastIndexOf(File.separator) + 1));
}
return tplm.cfg.getTemplate(name.substring(name
.lastIndexOf(File.separator) + 1));
}

/**
* @param templatefile
* 模板文件
* @param param
* 需要填充的内容
* @param out
* 填充完成输出的文件
* @throws IOException 
* @throws TemplateException 
*/
public static String process(String templatefile, Map param,
String docxTemplate) throws IOException, TemplateException {
FileOutputStream fos = null;
String templFilePath = null;
// 获取模板
try {
String zipFileName = com.sf.core.util.FileUtil.getTemplFilePath();
String dirName = zipFileName.substring(0,
zipFileName.lastIndexOf(File.separator));
File dir = new File(dirName);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(zipFileName);
fos = new FileOutputStream(file);
Writer out = new BufferedWriter(
new OutputStreamWriter(fos, "UTF-8"));// 生产文件输出流
Template template = XmlToDocx.getTemplate(templatefile);
template.setOutputEncoding("UTF-8");
// 合并数据
template.process(param, out);
out.flush();
templFilePath = com.sf.core.util.FileUtil.getTemplFilePath();
outDocx(file, docxTemplate, templFilePath);
} catch (IOException e) {
logger.error(e.getMessage(), e);
throw e;
} catch (TemplateException e) {
logger.error(e.getMessage(), e);
throw e;
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}
return templFilePath;
}

public static void outDocx(File documentFile, String docxTemplate,
String toFilePath) {
ZipFile zipFile = null;
ZipOutputStream zipout = null;
InputStream in = null;
FileOutputStream out = null;
InputStream is = null;
try {
File docxFile = new File(docxTemplate);
zipFile = new ZipFile(docxFile);
Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();
out = new FileOutputStream(toFilePath);
zipout = new ZipOutputStream(out);
int len = -1;
byte[] buffer = new byte[1024];
while (zipEntrys.hasMoreElements()) {
ZipEntry next = zipEntrys.nextElement();
is = zipFile.getInputStream(next);
// 把输入流的文件传到输出流中 如果是word/document.xml由我们输入
zipout.putNextEntry(new ZipEntry(next.toString()));
if ("word/document.xml".equals(next.toString())) {
in = new FileInputStream(documentFile);
while ((len = in.read(buffer)) != -1) {
zipout.write(buffer, 0, len);
}
} else {
while ((len = is.read(buffer)) != -1) {
zipout.write(buffer, 0, len);
}

}
}
} catch (IOException e) {
logger.error(e.getMessage(), e);
} finally {
close(zipout, in, out, is, zipFile);
}
}

public static void close(ZipOutputStream zipout, InputStream in,
FileOutputStream out, InputStream is, ZipFile zipFile) {

try {
if (zipout != null) {
zipout.close();
}
} catch (IOException e) {
logger.error(e.getMessage(), e);
}

if (out != null) {
try {
out.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
try {
if (zipFile != null) {
zipFile.close();
}
} catch (IOException e) {
logger.error(e.getMessage(), e);
}

try {
if (is != null) {
is.close();
}
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
try {
if (in != null) {
in.close();
}
} catch (IOException e1) {
logger.error(e1.getMessage(), e1);
}
}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值