1.将你的word模板根据下图插入需要填充的占位符,格式为${},大括号内放入传对应的值
2.审核者后面放的是一张电子签名的图片,这个位置将是我们要插入图片的位置
3.然后将你的word文件保存另存为xml文件
4.xml中可能看到的是这样$****{****}****隔开的,将中间的****删除掉,得到完整的${},如图
5.搜索<pkg:binaryData>,就可以看见一大串的字符串,这个是图片的base64码,如下图
6.可能会有多个大长字符串(注意:一个<pkg:binaryData></pkg:binaryData之间的长字符串代表一张图片),我的需求是要插入一张图片,将对应的长字符串删除用${image}代替,然后将xml文件改为ftl模板文件
搜索<w:pict>和<pkg:part>,他俩对应的是一张图片(多张图片就为多对),判断image不为空的时候才插入
8.我的需求是页面点击一个按钮,然后根据word模板生成报告
js代码
//生成报告按钮
tbarOpts.push({
text: '<i class="fa fa-file-word-o"></i>' + " 生成报告",
className: 'btn btn-sm btn-danger',
action:function(){
generateReport();
}
})
//生成报告的方法
function generateReport(){
var rows = $("#reportItem .selected");
if(!rows.length){
top.layer.msg(XXX.common.pleaseChoose);
return false;
}else if(rows.length > 1){
top.layer.msg(XXX.common.pleaseChooseOne);
return false;
}
var id = $(".selected").find("input").val();
top.layer.confirm("请确认修改保存后在生成报告",
{
icon : 3,
title : biolims.common.prompt,
btn:biolims.common.selected
},
function(index) {
top.layer.close(index);
window.open( ctx + "/reports/generateWorkReport.action?id=" + id);//后台的方法
top.layer.msg(XXX.report.generateReportSuccess);
});
}
java代码
将之前设置的占位符${}大括号里面的与map中的key保持一致
@Action(value = "generateWorkReport")
public void generateWorkReport() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
Map<String, Object> map = null;
String id = getRequest().getParameter("id");
User user = (User) this
.getObjFromSession(SystemConstants.USER_SESSION_KEY);
map = reportService.generateWorkReport(id, user);
User u = (User) map.get("auditUser");
if(u!=null) {
List<FileInfo> fileList = fileInfoService.findFileInfoList(u.getId(),"user");
if(fileList.size()>0) {
for (int i = 0; i<fileList.size() ; i++) {
FileInfo fileInfo = fileList.get(0);//审核人身上的电子签名文件
String fp = fileInfo.getFilePath();
String image = getImageBase(fp);//将电子签名文件转为base64码
map.put("image", image);
}
}else {
map.put("image", "");
}
}else {
map.put("image", "");
}
WordUtils.exportMillCertificateWord(request,response,map);
}
//获得图片的base64码
@SuppressWarnings("deprecation")
public 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);
}
生成word的工具类(注意templateFolder为模板存放的路径,将ftl模板放到该路径对应的文件夹中)
@SuppressWarnings("deprecation")
public class WordUtils {
private static Configuration configuration = null;
//这里注意的是利用WordUtils的类加载器动态获得模板文件的位置
//相当tomcat下webapps中的template文件夹,如果不知道打开本地tomcat下项目看下就知道了
private static final String templateFolder = WordUtils.class.getClassLoader().getResource("../../").getPath() + "template/";
static {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
try {
configuration.setDirectoryForTemplateLoading(new File(templateFolder));
} catch (IOException e) {
e.printStackTrace();
}
}
private WordUtils() {
throw new AssertionError();
}
public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map) throws IOException {
String fn = (String) map.get("fileName");
String[] split = fn.split(".doc");
//根据doc模板的名称,传入对应名称的ftl模板
String ftlName = split[0];
Template freemarkerTemplate = configuration.getTemplate(ftlName + ".ftl");
File file = null;
InputStream fin = null;
ServletOutputStream out = null;
try {
// 调用工具类的createDoc方法生成Word文档
file = createDoc(map,freemarkerTemplate);
fin = new FileInputStream(file);
response.setCharacterEncoding("utf-8");
response.setContentType("application/msword");
// 设置浏览器以下载的方式处理该文件名
String fileName = "检测报告单" + ".doc";
response.setHeader("Content-Disposition", "attachment;filename="
.concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
out = response.getOutputStream();
byte[] buffer = new byte[512]; // 缓冲区
int bytesToRead = -1;
// 通过循环将读入的Word文件的内容输出到浏览器中
while((bytesToRead = fin.read(buffer)) != -1) {
out.write(buffer, 0, bytesToRead);
}
} finally {
// 生成word后清除临时文件
if(fin != null) fin.close();
if(out != null) out.close();
if(file != null) file.delete();
}
}
private static File createDoc(Map<?, ?> dataMap, Template template) {
//具体的文件
String filePath = (String) dataMap.get("filePath");
// String name = "d:\\test.doc";
File f = new File(filePath);
Template t = template;
try {
// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
t.process(dataMap, w);
w.close();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
return f;
}
}