在工作中又遇到要導出word,根據模板導出,里面有一部分內容數據事動態的,需要循環根據數據導出。
一、首先准備word模板
1、在word里面講格式調整好,在需要導出圖片的地方填充圖片。
需要填充數據的地方用字段名代替。以便於修改為el表達式,也可以直接在模板里面直接用EL表達式,定義好,比如這樣:
2、另存為 類型為 word 2003 xml
3、將xml文件打開,可以看到已經是xml格式了。可以將內容全部復制到xml格式化網站,進行格式化之后,這樣就好看多了嘛
4、然后將文件復制到你項目,改文件后綴為ftl
二、准備導出數據
1、首先在項目里面引入freemaker依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>2.6.1</version>
</dependency>
2、准備要導出的數據結構,這里只展示幾個字段
@Data
public class RecordExportTO implements Serializable { private String title; private String feedbackName; private String feedbackPhone; private String diagnosisNo; private List<StTemplateQuestion> questionsList;//動態數據內容 private String faultImg; private List<ExportWordImgVo> faultImgList;//圖片集合 }
3、修改模板,根據數據結構字段,將需要填充數據的地方,修改為EL表達式。${()!} 加括號!號表示可以為null
動態數據內容部分,根據你需要動態輸出的,部分進行循環,我這里是表格一行循環。
在循環里面,根據自己的業務處理
圖片處理:
注意!!!
圖片base64編碼內容,兩個>${img.content}< 中間不能有空格!
三、導出
我是接口http導出
@Autowired
private Configuration configuration; //freemarker.template.Configuration;
@GetMapping("/export/{id}")
public void exportById(@PathVariable Integer id,HttpServletResponse response) {
RecordExportTO data =new RecordExportTO();
//准備數據部分,省略--
//圖片 List<ExportWordImgVo> faultImgList = findXls(record.getFaultImg(),xls);//這里這個函數是我得業務邏輯處理,返回的是多張圖片的base64編碼 data.setFaultImgList(faultImgList);
//導出 configuration.setDefaultEncoding("utf-8");
try { response.setContentType("application/msword");
response.setHeader("Content-Disposition", "attachment;filename=\"" + new String(record.getDiagnosisNo().getBytes("utf-8"), "iso8859-1") + ".doc\"");//導出word文件名
response.setCharacterEncoding("utf-8"); final Template template = configuration.getTemplate("word/record.ftl", "utf-8");//模板位置
template.process(data, new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), "utf-8")));
} catch (Exception e) {
log.error("導出失敗", e);
}finally {
try {
response.getOutputStream().close();
} catch (IOException e) { e.printStackTrace(); }
}
}
//根據url返回圖片的base64編碼 導出的word里面需要base64格式的 private String getImgBase64(String url){ HttpClient client = HttpClients.custom().build(); HttpGet get = new HttpGet(url); HttpResponse response; try { response = client.execute(get); if (response.getStatusLine().getStatusCode() == 200) { // 得到實體 HttpEntity entity = response.getEntity(); byte[] data = EntityUtils.toByteArray(entity); return new String(Base64.encodeBase64(data)); } else { logger.error("下載文件url 錯誤返回:{}",response); return null; } } catch (IOException e) { e.printStackTrace(); logger.error("下載文件url 錯誤:",e); } return null; }
//圖片class
public class ExportWordImgVo implements Serializable {
private String id;//自定義id
private String name;//圖片名
private String content;//圖片base64碼
}
訪問這個接口,就可以導出啦