Word从2003开始支持XML格式,用XML还做就很简单了。
大致的思路是先用office2003或者2007编辑好word的样式,然后另存为xml,如下图所示:
将xml翻译为FreeMarker模板,最后用java来解析FreeMarker模板并输出Doc,如图所示的操作:
后台生成word的代码如下:
package net.gvsun.service;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class WordHandler {
private Configuration configuration = null;
public WordHandler() {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
}
public File createDoc(String templatePath, String templateName, Map dataMap,String fileName) {
/* // 要填入模本的数据文件
Map dataMap = new HashMap();
getData(dataMap);*/
// 设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载,
// ftl文件存放路径
configuration.setClassForTemplateLoading(this.getClass(), templatePath);
Template t = null;
try {
// test.ftl为要装载的模板
t = configuration.getTemplate(templateName);
t.setEncoding("utf-8");
} catch (IOException e) {
e.printStackTrace();
}
// 输出文档路径及名称
String root = System.getProperty("dhulims.root");
String upLoad=root+"upload"+File.separator;
// File sendPath = new File(upLoad+projectNO);
File file = new File(upLoad);
if(!file.exists()){
file.mkdirs();
}
File outFile = new File(upLoad+fileName+".doc");
Writer out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"));
} catch (Exception e1) {
e1.printStackTrace();
}
try {
t.process(dataMap, out);
/*out.close();*/
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return outFile;
}
public static void main(String templatePath, String templateName, Map dataMap,String fileName) {
new WordHandler().createDoc(templatePath,templateName,dataMap,fileName);
}
}
control导出word并传入参数的代码如下:
/**
* 下载实验项目的word文档
* 作者:彭文玉
*/
@RequestMapping("/downloadLmsExperiment")
public void downloadLmsExperiment(@RequestParam int idKey,HttpServletResponse response)
{
response.setContentType("application/doc;charset=UTF-8");
byte b[] = new byte[1024];
//转换startDate的时间格式;
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
//根据主键idKey查找到LmsExperiment
LmsExperiment lmsexperiment=lmsExperimentDAO.findLmsExperimentByPrimaryKey(idKey);
//如果lmsexperiment的系部不为空
if(lmsexperiment.getSysDepartment()!=null){
//映射lmsexperiment的departmentName给departName;
dataMap.put("departName",lmsexperiment.getSysDepartment().getDepartmentName());
}
//否则设置lmsexperiment的null为departName
else{
dataMap.put("departName", "");
}
//映射lmsexperiment的experimentNumber给experimentNumber;
dataMap.put("experimentNumber",lmsexperiment.getExperimentNumber());
//映射Experiment的ExperimentName给ExperimentName;
dataMap.put("ExperimentName",lmsexperiment.getExperimentName());
//映射lmsexperiment的experimentCardNumber给experimentCardNumber;
dataMap.put("experimentCardNumber",lmsexperiment.getExperimentCardNumber());
//映射lmsexperiment的experimentMajor给experimentMajor;
dataMap.put("experimentMajor",lmsexperiment.getExperimentMajor());
//映射lmsexperiment的totalCourseHours给totalCourseHours;
dataMap.put("totalCourseHours",lmsexperiment.getTotalCourseHours());
//映射lmsexperiment的totalExperimentHours给totalExperimentHours;
dataMap.put("totalExperimentHours",lmsexperiment.getTotalExperimentHours());
//映射lmsexperiment的thisExperimentHours给thisExperimentHours;
dataMap.put("thisExperimentHours",lmsexperiment.getThisExperimentHours());
//映射lmsexperiment的experimentEachNumber给experimentEachNumber;
dataMap.put("experimentEachNumber",lmsexperiment.getExperimentEachNumber());
//映射lmsexperiment的experimentGroup给experimentGroup;
dataMap.put("experimentGroup",lmsexperiment.getExperimentGroup());
//映射lmsexperiment的experimentCreatedAt给experimentCreatedAt;
dataMap.put("experimentCreatedAt",sdf.format(lmsexperiment.getExperimentCreatedAt().getTime()));
//映射lmsexperiment的experimentChangelog给experimentChangelog;
dataMap.put("experimentChangelog",lmsexperiment.getExperimentChangelog());
//映射lmsexperiment的experimentDesign给experimentDesign;
dataMap.put("experimentDesign",lmsexperiment.getExperimentDesign());
//映射lmsexperiment的experimentRequired给experimentRequired;
dataMap.put("experimentRequired",lmsexperiment.getExperimentRequired());
//映射lmsexperiment的experimentPurposes给experimentPurposes;
dataMap.put("experimentPurposes",lmsexperiment.getExperimentPurposes());
//映射lmsexperiment的experimentAward给experimentAward;
dataMap.put("experimentAward",lmsexperiment.getExperimentAward());
//如果lmsexperiment的学院不为空
if(lmsexperiment.getSysAcademy()!=null){
//映射lmsexperiment的AcademyName给academyName;
dataMap.put("academyName",lmsexperiment.getSysAcademy().getAcademyName());
}
//否则设置lmsexperiment的null为academyName
else{
dataMap.put("academyName", "");
}
//如果lmsexperiment的课程不为空
if(lmsexperiment.getSysCourse()!=null){
//映射lmsexperiment的CourseName给courseName;
dataMap.put("courseName",lmsexperiment.getSysCourse().getCourseName());
}
//否则设置lmsexperiment的null为courseName
else{
dataMap.put("courseName","");
}
//如果lmsexperiment的实验室不为空
if(lmsexperiment.getLmsLab()!=null){
//映射lmsexperiment的labName给labName;
dataMap.put("labName",lmsexperiment.getLmsLab().getLabName());
}
//否则设置lmsexperiment的null为courseName
else{
dataMap.put("courseName","");
}
//如果lmsexperiment的项目类型不为空
if(lmsexperiment.getDataFieldByExperimentCategory()!=null){
//映射lmsexperiment的categoryName给categoryName;
dataMap.put("categoryName",lmsexperiment.getDataFieldByExperimentCategory().getName());
}
//否则设置lmsexperiment的null为categoryName
else{
dataMap.put("categoryName","");
}
WordHandler handler = new WordHandler();
//生成word
File outFile =handler.createDoc("/com/ftl", "AA.ftl", dataMap,lmsexperiment.getExperimentName());
//下面的代码是导出word
FileInputStream in = null;
OutputStream o = null;
try {
in = new FileInputStream(outFile);
o = response.getOutputStream();
response.setContentType("application/x-tar");
response.setHeader("Content-disposition", "attachment; filename="
+ URLEncoder.encode(lmsexperiment.getExperimentName()+".doc", "UTF-8"));// 指定下载的文件名
response.setHeader("Content_Length",String.valueOf( outFile.length())); // download the file.
int n = 0;
while ((n = in.read (b))!= -1)
{
o.write(b, 0, n);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
in.close();
o.flush();
o.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
经测试这样方式生成导出word文档完全符合office标准,样式、内容控制非常便利,打印也不会变形,生成的文档和office中编辑文档完全一样。