公司最近需要实现word导出功能,并且要去需要用到freemarker模板形式。由于之前只做过poi的Excel导出,对word导出陌生的很。这次算是有机会接触,赶紧记下来。
要求模板:
红色框部分、单选、多选要求均为变量
接下来就是代码的实现部分
1. 替换模板变量
先把文字部分变量替换成所需值
2. 创建实体对象
@Data
public class NursingRecordWordEntity implements Serializable {
private static final long serialVersionUID = 6435335655833720074L;
/**
* 患者姓名
*/
private String patName;
/**
* 记录时间
*/
private String dateTime;
/**
* 记录人
*/
private String recorder;
/**
* 住院号
*/
private String admissionNumber;
/**
* 床号
*/
private String bedNo;
/**
* 入院日期
*/
private String date;
/**
* 诊断
*/
private String diagnose;
/**
* 左瞳孔
*/
private String leftPupil;
/**
* 右瞳孔
*/
private String rightPupil;
/**
* 体温
*/
private String temp;
/**
* 脉搏
*/
private String pulse;
/**
* 呼吸
*/
private String breathe;
/**
* 心率
*/
private String heartRate;
/**
* 血压
*/
private String bloodPressure;
/**
* 氧饱和度
*/
private String spo;
/**
* 氧流量
*/
private String oxygenflow;
/**
* 血糖
*/
private String glu;
/**
* cvp
*/
private String cvp;
/**
* 意识: 清醒 模糊 嗜睡 昏睡 浅昏睡 深昏睡 谵妄状态
*/
private String consciousness;
/**
* 病情: 重 危 管通
*/
private String condition;
/**
* 卧位: 左 右 平卧 端坐 俯 仰 半坐 半卧
*/
private String clinostatism;
/**
* 左眼球摘除
*/
private String leftPupilRemove;
/**
* 右眼球摘除
*/
private String reghtPupilRemove;
/**
* 左眼球瞳孔消失mm
*/
private String leftPupilDieMM;
/**
* 右眼球瞳孔消失mm
*/
private String reghtPupilDieMM;
/**
* 皮肤: 压疮 出血点 颇损 水肿 浸渍 红疹 青紫 肿胀 完整
*/
private String skin;
/**
* 体温类型 :腋度 肛度 耳度 口温 膀胱温度
*/
private String tempType;
/**
* 心电监护
*/
private String ecg;
/**
* 吸痰
*/
private String sputum;
/**
* 皮肤状态(多选)
*/
/**
*压疮
*/
private Boolean pressureSore = false;
/**
*出血点
*/
private Boolean bloodPoint = false;
/**
*颇损
*/
private Boolean damaged = false;
/**
*水肿
*/
private Boolean edema = false;
/**
*浸渍
*/
private Boolean dipping = false;
/**
*红疹
*/
private Boolean erythema = false;
/**
*青紫
*/
private Boolean cyanoze = false;
/**
*肿胀
*/
private Boolean swell = false;
/**
*完整
*/
private Boolean full = false;
}
3. 引入freemarker依赖包
4. 把替换好变量的word文档另存为.xml
5. 使用Notepad++等编辑软件打开,对单选、多选进行操作
切记!单选符号、多选符号并不是搜狗输入法里面查询特殊。而是在word的特殊字符中找到想要的效果( Word > 插入 > 符号 > 其他符号(M)..), 也就是字体 Wingdings有我们需要的特殊字符
单选:
<w:sym w:font="Wingdings" w:char="00A4"/>
<w:sym w:font="Wingdings" w:char="00A1"/>
多选:
<w:sym w:font="Wingdings" w:char="00FE"/>
<w:sym w:font="Wingdings" w:char="00A8"/>
然后使用freemarker语法修改.xml内容(例)
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:b w:val="0"/>
<w:bCs w:val="0"/>
<w:sz w:val="16"/>
<w:szCs w:val="20"/>
<w:vertAlign w:val="baseline"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<#if reghtPupilRemove == "眼球摘除">
<w:sym w:font="Wingdings" w:char="00A4"/>
<#else>
<w:sym w:font="Wingdings" w:char="00A1"/>
</#if>
</w:r>
<w:r>
修改完毕另存为后缀 .ftl 文件
6. 修改完毕放入项目目录
7. 代码实现
public class DocumentHandler {
private Configuration configuration = null;
public DocumentHandler() {
configuration = new Configuration(Configuration.VERSION_2_3_28);
configuration.setDefaultEncoding("utf-8");
}
public void createDoc() {
//要填入模本的数据文件
NursingRecordWordEntity data=new NursingRecordWordEntity();
getData(data);
//设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库教程装载,
configuration.setClassForTemplateLoading(this.getClass(),"/template");
Template t=null;
try {
//test.ftl为要装载的模板
t = configuration.getTemplate("nursingRecord.ftl");
} catch (IOException e) {
e.printStackTrace();
}
//输出文档路径及名称
File outFile = new File("H:\\home\\new_记录单导出模板.docx");
Writer out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
t.process(data, out);
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 注意:
* 如果是Map那么存放的数据Key值要与模板中的参数相对应
* 如果是java Bean那么属性名要和模板中的参数相对应
*/
private void getData(NursingRecordWordEntity data){
data.setPatName("王二");
data.setRecorder("老教师");
data.setAdmissionNumber("123123");
data.setBedNo("123");
data.setDate("2019-10-12");
data.setDateTime("2019-10-12 10:12:33");
data.setLeftPupil("15");
data.setLeftPupilRemove(false);
data.setRightPupil("12");
data.setReghtPupilRemove(true);
data.setTemp("60");
data.setPulse("12");
data.setBreathe("120");
data.setHeartRate("120");
data.setBloodPressure("740/1000");
data.setSpo("60");
data.setOxygenflow("99");
data.setGlu("xx");
data.setCvp("61");
data.setClinostatism("左");
data.setCondition("重");
data.setConsciousness("昏睡");
data.setSkin("出血点");
data.setTempType("肛度");
data.setEcg("室早");
data.setSputum("吸痰");
}
public static void main(String[] args){
DocumentHandler dh=new DocumentHandler();
dh.createDoc();
}
}
后续
如果想使用流导出只需要如下实现
@RequestMapping(value = "/exportWord")
public void exportTemplate(NursingRecordWordEntity entity, HttpServletResponse response) {
log.info("start exportTemplate request is {}", JSON.toJSON(entity));
ExportWordUtils.createDoc(response, nursingRecordControllerFacade.buildData(entity), EXPORT_WORD_TEMPLATE_NAME, "护理明细doc_" + +System.currentTimeMillis() + ".doc");
log.info("end exportTemplate..");
}
public static void createDoc(HttpServletResponse response , Object obj , String templateName , String name) {
initTemplate();
Template t = null;
try {
t = FTL_CFG.getTemplate(templateName, DEFAULT_CHARSET);
} catch (IOException e) {
throw new GWIException("匹配模板获取失败..");
}
Writer w = null;
try {
// 告诉浏览器用什么软件可以打开此文件
response.setContentType("application/vnd.ms-excel;charset=utf-8");
// 下载文件的默认名称
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name, "utf-8"));
w = response.getWriter();
t.process(obj, w);
w.close();
} catch (UnsupportedEncodingException e) {
throw new GWIException(e.toString());
} catch (IOException e) {
throw new GWIException(e.toString());
} catch (TemplateException e) {
throw new GWIException(e.toString());
}
}
至此...word导出功能实现完毕。欢迎大家留言