使用freemarker导出world每次修改都需要重新制作模板 ,这样会浪费大量时间。经过长期使用freemarker发现他的利弊如下
利:可以通过freemarker将导航栏的接口展现出来,poi导出是无法实现的。
弊:freemarker使用的是ftl语言,如果需要替代数据中存在"<“、”>"大于号或者小于号的话,freemarker无法区分替代值和ftl标签,会导致报错。
通过poi实现导出只需将需要代替数据在模板中做好标识,通过JAVA方法替代就可以了,具体实现如下
Controller层
/**
* 导出检修工单检修详情
*/
@RequestMapping("export_world")
@ResponseBody
public void exportWorld(@RequestBody FasOverhaulYearPlanExt ext, HttpServletResponse response) throws IOException {
performedService.exportWorld(ext,response);
}
Service层
/**
* 导出检修工单检修详情
*/
public void exportWorld(FasOverhaulYearPlanExt ext, HttpServletResponse response) throws IOException {
// String BASE_TEMPLATE_PATH = constant.getOverhaulPath();
// 1.读取模板
String BASE_TEMPLATE_PATH = "D:/femsproject/gw-ercp-fems-server/gw-ercp-fems-web/src/main/resources/templates";
String fileName = "V20";
File templateFile = new File(BASE_TEMPLATE_PATH + "/maintenance/" + fileName + ".docx");
XWPFDocument word = new XWPFDocument(new FileInputStream(templateFile));
// 2.业务信息处理
HashMap<String, String> params = new HashMap<>();
params.put("fileno","GWT-996");
ArrayList<HashMap<String, String>> list = new ArrayList<>();
list.add(params);
// 3.替换数据
// 处理正文开始
List<XWPFParagraph> paragraphs = word.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
String text = run.getText(0);
for (String key : params.keySet()){
if(StringUtil.isNotEmpty(text)){
run.setText(text.replaceAll(key,params.get(key)),0);
}
}
}
}
// 处理正文结束
// 4.①自定义表格
// 创建表格 3:三行 8:八列
XWPFTable table1 = word.createTable(3, 8);
// 创建第一行抬头
XWPFTableRow row = table1.getRow(0);
row.getCell(0).setText("步骤");
CTTcPr ctTcPr = row.getCell(0).getCTTc().addNewTcPr();
CTTblWidth cellw = ctTcPr.addNewTcW();
cellw.setType(STTblWidth.DXA);
cellw.setW(BigInteger.valueOf(900));
row.getCell(1).setText("检修项");
CTTcPr ctTcPr1 = row.getCell(1).getCTTc().addNewTcPr();
CTTblWidth cellw1 = ctTcPr1.addNewTcW();
cellw1.setType(STTblWidth.DXA);
cellw1.setW(BigInteger.valueOf(2000));
row.getCell(2).setText("检查/维护操作");
CTTcPr ctTcPr2 = row.getCell(2).getCTTc().addNewTcPr();
CTTblWidth cellw2 = ctTcPr2.addNewTcW();
cellw2.setType(STTblWidth.DXA);
cellw2.setW(BigInteger.valueOf(2400));
row.getCell(3).setText("标准");
CTTcPr ctTcPr3 = row.getCell(3).getCTTc().addNewTcPr();
CTTblWidth cellw3 = ctTcPr3.addNewTcW();
cellw3.setType(STTblWidth.DXA);
cellw3.setW(BigInteger.valueOf(2500));
row.getCell(4).setText("检查状态");
CTTcPr ctTcPr4 = row.getCell(4).getCTTc().addNewTcPr();
CTTblWidth cellw4 = ctTcPr4.addNewTcW();
cellw4.setType(STTblWidth.DXA);
cellw4.setW(BigInteger.valueOf(1200));
row.getCell(5).setText("处理过程");
CTTcPr ctTcPr5 = row.getCell(5).getCTTc().addNewTcPr();
CTTblWidth cellw5 = ctTcPr5.addNewTcW();
cellw5.setType(STTblWidth.DXA);
cellw5.setW(BigInteger.valueOf(1800));
row.getCell(6).setText("最终状态");
CTTcPr ctTcPr6 = row.getCell(6).getCTTc().addNewTcPr();
CTTblWidth cellw6 = ctTcPr6.addNewTcW();
cellw6.setType(STTblWidth.DXA);
cellw6.setW(BigInteger.valueOf(1200));
row.getCell(7).setText("记录");
// 设置单元格宽度
CTTcPr ctTcPr7 = row.getCell(7).getCTTc().addNewTcPr();
CTTblWidth cellw7 = ctTcPr7.addNewTcW();
cellw7.setType(STTblWidth.DXA);
cellw7.setW(BigInteger.valueOf(2500));
// 创建第一行抬头
XWPFTableRow row2 = table1.getRow(1);
row2.getCell(0).setText("步骤1");
row2.getCell(1).setText("检修项内容");
// 将表格放入参数中
// 8:模板中代表第8个表格
word.setTable(8,table1);
// ②.现有表格写入数据
// get(0)模板中第1个表格
XWPFTable xwpfTable = word.getTables().get(0);
XWPFTableRow row1 = xwpfTable.getRow(0);
int rowIndex = 1;
for (HashMap<String,String> map : list){
// 添加行
xwpfTable.addRow(row1);
this.copyRow(xwpfTable,row1,rowIndex);
row1.getCell(0).setText("第一列值");
row1.getCell(1).setText("第二列值");
row1.getCell(2).setText("第三列值");
// 将图片转成流
File imageFile = new File("图片地址");
this.setCellImage(row1.getCell(3),imageFile);
rowIndex ++;
}
// 4.导出world
String exportFileName = fileName + ".docx";
response.setHeader("content-disposition","attachment;filename=" + new String(exportFileName.getBytes(),"ISO8859-1"));
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
word.write(response.getOutputStream());
}
/**
* 行数据克隆
*/
private void copyRow(XWPFTable xwpfTable, XWPFTableRow sourceRow, int rowIndex){
XWPFTableRow targetRow = xwpfTable.insertNewTableRow(rowIndex);
targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
// 获取源行的单元格
List<XWPFTableCell> cells = sourceRow.getTableCells();
if (CollectionUtils.isNotEmpty(cells)){
return;
}
XWPFTableCell targetCell = null;
for (XWPFTableCell cell : cells){
targetCell = targetRow.addNewTableCell();
// 附上单元格样式
// 单元格的属性
targetCell.getCTTc().setTcPr(cell.getCTTc().getTcPr());
targetCell.getParagraphs().get(0).getCTP().setPPr(cell.getParagraphs().get(0).getCTP().getPPr());
}
}
/**
* 向单元格中写入图片
*/
private void setCellImage(XWPFTableCell cell, File imageFile){
XWPFRun run = cell.getParagraphs().get(0).createRun();
try (FileInputStream inputStream = new FileInputStream(imageFile)){
run.addPicture(inputStream,XWPFDocument.PICTURE_TYPE_JPEG,imageFile.getName(), Units.toEMU(100),Units.toEMU(50));
} catch (Exception e){
e.printStackTrace();
}
}