前言
一開始客戶要求做word導出時,只是將系統的一個表單內容導出到word中,沒有富文本的數據。這種情況導出word就很簡單,製作好word模板後,直接使用easypoi的api就行。後來表單的一個文本框改爲了富文本,同時也要求導出的時候呈現的格式和富文本中輸入的格式一樣。這時候easypoi就行不通了,搜索了網上資料以及結合自己的項目要求做了一下總結。
技術點剖析
- 由於富文本存入數據庫的字符串是帶有html元素標籤的,所以使用doc爲文件爲導出模板是不行的,它無法將這種字符串翻譯成html的形式,只會展示出帶有html標籤的字符,所以需要重新構建模板文件使得它能支持html文本
- 富文本如果含有圖片,需要進行額外的處理
- 不能使用easypoi的api,涉及到中文字符的轉碼需要自行處理
解決方案
創建新的模板
這裏使用.mht類型的文件作爲模板文件,製作的方法如下:
- 首先先製作一個doc類型的模板文件,設計好表單的樣式,填入佔位符
- 調整好格式後,將doc文件另存爲.mht文件
- 可以使用notepad++打開.mht文件,雖然看不懂裏面的內容,但是可以看到之前設計的佔位符是存在的
代碼階段的思路就是:
1.讀取模板文件的內容
2.獲得需要導出的內容,可以是一個map,也可以是一個對象
3.使用導出內容替換掉模板內容字符串的佔位符
4.經過轉碼處理之後輸出到輸出流裏進行導出
代碼處理
Map<String, String> resultMap = initExportStringMap(caseInfo, caseDealInfo);
OutputStream os = null;
//導出word
try {
//獲取模板文件的路徑
File file = ResourceUtils.getFile("classpath:static/excel/市長熱線來電受理登記表.mht");
String templeteContent = FileUtils.readTemplete(file);
if (StringUtils.isNoneBlank(templeteContent)) {
//替換模板文件的佔位符
templeteContent = DownloadUtil.replaceTempleteContenet(templeteContent, resultMap);
//轉碼
templeteContent = FileUtils.string2ASCII(templeteContent);
os = response.getOutputStream();
response.reset();
response.setCharacterEncoding("utf-8");
//導出爲doc格式
response.setContentType("application/msword");
response.setHeader("Content-Disposition", "attachment; filename=" + "市長熱線來電受理登記表");
byte[] b = templeteContent.getBytes("UTF-8");
os.write(b);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (os != null) {
os.flush();
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
讀取資源文件
/**
* 讀取資源文件中的mht模板文件
* @param file
* @return
* @throws IOException
*/
public static String readTemplete(File file)throws IOException{
StringBuffer buffer = new StringBuffer("");
BufferedReader br = null;
try {
buffer = new StringBuffer("");
br = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8"));
while (br.ready()){
buffer.append((char)br.read());
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
if(br!=null){
br.close();
}
}
return buffer.toString();
}
替換佔位符很簡單,replace方法就可
轉碼處理
/**
* 完成佔位符替換後需要將mht字符轉碼,因爲mht採用3Dus-ascii編碼,
* 該編碼格式爲10進制的ASCII碼(非16進制)
* 如果不進行處理,會導致最終導出的文件中有中文亂碼
* @param s
* @return
*/
public static String string2ASCII(String s) {
if(s==null||"".equals(s)) {
return null;
}
char[] chars=s.toCharArray();
StringBuffer asciiString=new StringBuffer();
int n=0;
for(char c:chars) {
n=c;
String a="";
if((19968<=n && n<40623)) {
a="&#"+n+";";
}else {
a=c+"";
}
asciiString.append(a);
}
return asciiString.toString();
}
這樣導出就做好了,導出的doc文檔打開後會默認使用web視圖打開,可切換視圖查看效果