近日需要將人員的基本信息導出,存儲為word文檔,查閱了很多資料,最后選擇了使用freemarker,網上一共有四種方式,效果都一樣,選擇它呢是因為使用簡單,再次記錄一下,一個簡單的demo,僅供參考。
1.引入依賴:
org.freemarker
freemarker
2.3.20
2.word工具類
package com.bfd.bose_kotwalee_screen_data.util.word;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.utility.DateUtil;
import org.apache.directory.api.util.DateUtils;
public class WordUtils {
private static Configuration configuration = null;
//class.getResource()可以獲取絕對路徑和相對路徑
private static final String templateFolder = WordUtils.class.getResource("/templates").getPath();
static {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
try {
configuration.setDirectoryForTemplateLoading(new File(templateFolder));
} catch (IOException e) {
e.printStackTrace();
}
}
private WordUtils() {
throw new AssertionError();
}
public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map, String title, String ftlFile) throws IOException {
Template freemarkerTemplate = configuration.getTemplate(ftlFile);
File file = null;
InputStream fin = null;
ServletOutputStream out = null;
try {
// 調用工具類的createDoc方法生成Word文檔
file = createDoc(map, freemarkerTemplate);
fin = new FileInputStream(file);
response.setCharacterEncoding("utf-8");
response.setContentType("application/msword");
// 設置瀏覽器以下載的方式處理該文件名 + DateUtils.getDate("2019-08-29")
String fileName = title + ".doc";
response.setHeader("Content-Disposition", "attachment;filename="
.concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
out = response.getOutputStream();
byte[] buffer = new byte[512]; // 緩沖區
int bytesToRead = -1;
// 通過循環將讀入的Word文件的內容輸出到瀏覽器中
while ((bytesToRead = fin.read(buffer)) != -1) {
out.write(buffer, 0, bytesToRead);
}
} finally {
if (fin != null) {
fin.close();
}
if (out != null) {
out.close();
}
if (file != null) {
file.delete(); // 刪除臨時文件
}
}
}
private static File createDoc(Map, ?> dataMap, Template template) {
String name = "sellPlan.doc";
File f = new File(name);
Template t = template;
try {
// 這個地方不能使用FileWriter因為需要指定編碼類型否則生成的Word文檔會因為有無法識別的編碼而無法打開
Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
t.process(dataMap, w);
w.close();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
return f;
}
}
3.service代碼
public void exportSellPlan(HttpServletRequest request, HttpServletResponse response) {
Calendar calendar = Calendar.getInstance();// 取當前日期。
//圖片地址
String imagePath = WordUtils.class.getResource("/img").getPath()+"/test.jpg";
//獲得數據
Map map = new HashMap<>();
List> list = new ArrayList<>();
Map m;
for (int i = 0;i<3;i++){
m = new HashMap<>();
m.put("name","張三" + i);
m.put("age","" + 13 + i);
list.add(m);
}
map.put("list",list);
map.put("img",this.getImageBase(imagePath));
try {
//table.ftl為word模板
WordUtils.exportMillCertificateWord(request, response, map, "簡歷方案", "table.ftl");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//獲得圖片的base64碼
@SuppressWarnings("deprecation")
public String getImageBase(String src) {
if(src==null||src==""){
return "";
}
File file = new File(src);
if(!file.exists()) {
return "";
}
InputStream in = null;
byte[] data = null;
try {
in = new FileInputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
4.模板制作
1)制作word模板,另存為.xml文件
image.png
2)將.xml文件上傳到工程中,并修改為.ftl后綴
image.png
這個路徑在下面這行代碼設定
private static final String templateFolder = WordUtils.class.getResource("/templates").getPath();
完成以上步驟,導出word功能就完成了。
注意:制作模板的時候,${name}綁定字段的時候在.ftl文件或被默認拆分,需要手動修改一下。封裝數據的時候要和模板一一對應,數據為空的話也要添加,模板中的字段名在封裝的數據必須有。