一·、製作模板
1、打開world模板,在需要填入的地方寫入佔位符:
PS:佔位符格式"${佔位符名稱}",需事先規定好填充數據的字體樣式及大小,需要加入圖片的地方直接放入一張圖片
2、 將填充好佔位符的world文檔另存爲xml文件
3、 將存的.xml文件重命名爲.ftl後綴,例中重命名後爲:entryform.ftl
4、用編輯器打開.ftl文件,因爲在將world文檔轉換爲.xml文件時,會使我們之前設置好的佔位符位置隔開,所以這裏我們需要將佔位符中間隔的代碼全部刪除,保持佔位符格式
5、替換圖片佔位符:
找到圖片的64位編碼
將<pkg:binaryData></pkg:binaryData>標籤中的圖片編碼用佔位符替換掉
6、保存退出,模板製作完成
二、代碼使用:
1、將模板放到/resources/templates/下
2、映入worldutils工具類:
package com.zpw.back.util;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Encoder;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
/**
* @author Hu Wentao
* @date 2020/4/6-12:13
*/
@Component
public class WordUtil {
/**
* 生成word文件
* @param dataMap word中需要展示的動態數據,用map集合來保存
* @param templateName word模板名稱,例如:test.ftl
* @param filePath 文件生成的目標路徑,例如:D:/wordFile/
* @param fileName 生成的文件名稱,例如:test.doc
*/
public static void createWord(Map dataMap,String templateName,String filePath,String fileName){
try {
//創建配置實例
Configuration configuration = new Configuration();
//設置編碼
configuration.setDefaultEncoding("UTF-8");
//ftl模板文件
configuration.setClassForTemplateLoading(WordUtil.class,"/");
//獲取模板
Template template = configuration.getTemplate(templateName);
//輸出文件
File outFile = new File(filePath+File.separator+fileName);
//如果輸出目標文件夾不存在,則創建
if (!outFile.getParentFile().exists()){
outFile.getParentFile().mkdirs();
}
//將模板和數據模型合併生成文件
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));
//生成文件
template.process(dataMap, out);
//關閉流
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//獲取文件裏的圖片
public String getImageStr(String imgFile) {
InputStream in = null;
byte[] data = null;
try {
if(imgFile.startsWith("http")){ //獲取在線圖片
URL url = new URL(imgFile);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(20 * 1000);
in = conn.getInputStream();
}else{ //獲取線下圖片
in = new FileInputStream(imgFile);
}
//使用此種方式在獲取在線圖片時下載word中圖片可能顯示不全,其原因就是網絡通訊往往是間斷性的,一串字節往往分幾批進行發送。本地程序調用available()方法有時得到0,這可能是對方還沒有響應,也可能是對方已經響 應了,但是數據還沒有送達本地。對方發送了1000個字節給你,也許分成3批到達,這你就要調用3次available()方法才能將數據總數全部得到。
/*int count = 0;
while (count == 0) {
count = in.available();
}
data = new byte[count];*/
int c;
ByteArrayOutputStream buff = new ByteArrayOutputStream();
while((c = in.read()) >= 0){
buff.write(c);
}
data = buff.toByteArray();
buff.close();
in.read(data);
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
if(data!=null && data.length>0){
return encoder.encode(data);
}
return null;
}
}
3、封裝填充數據:
PS:這裏需要注意的兩點:第一,日期格式應該做轉換;第二,圖片的填充略有不同
//生成報名表,存放於服務器中
//用於組裝word頁面需要的數據
Map<String, Object> dataMap = new HashMap<String, Object>();
//轉換時間格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
//和前端約定部門傳部門id,這裏通過部門id查出部門名稱
Department department = departmentService.findById(employee.getDepartmentId());
/** 組裝數據 */
dataMap.put("id", employee.getId());
dataMap.put("picture", wordUtil.getImageStr(employee.getPicture()));
dataMap.put("departmentId", department.getName());
dataMap.put("name", employee.getName());
dataMap.put("sex", employee.getSex());
dataMap.put("birthday", simpleDateFormat.format(employee.getBirthday()));
dataMap.put("political_landscape", employee.getPolitical_landscape());
dataMap.put("national", employee.getNational());
dataMap.put("marriage", employee.getMarriage());
dataMap.put("native_place", employee.getNative_place());
dataMap.put("qualifications", employee.getQualifications());
dataMap.put("professional_and_technical_titles", employee.getProfessional_and_technical_titles());
dataMap.put("first_academic", employee.getFirst_academic());
dataMap.put("first_degree", employee.getFirst_degree());
dataMap.put("first_academic_major", employee.getFirst_academic_major());
dataMap.put("first_academic_graduatedschool", employee.getFirst_academic_graduatedschool());
dataMap.put("first_academic_graduatedtime", employee.getFirst_academic_graduatedtime());
dataMap.put("highest_academic", employee.getHighest_academic());
dataMap.put("highest_degree", employee.getHighest_degree());
dataMap.put("highest_academic_major", employee.getHighest_academic_major());
dataMap.put("highest_academic_graduatedschool", employee.getHighest_academic_graduatedschool());
dataMap.put("highest_academic_graduatedtime", employee.getHighest_academic_graduatedtime());
dataMap.put("address", employee.getAddress());
dataMap.put("zip_code", employee.getZip_code());
dataMap.put("phone", employee.getPhone());
dataMap.put("email", employee.getEmail());
dataMap.put("resume", employee.getResume());
4、代碼中調用:
/**
* 第一個參數:封裝的佔位符數據,類型:Map<String,Object>
* 第二個參數:模板位置
* 第三個參數:生成的文件的存放路徑
* 第四個參數:生成world的文件名
* /
wordUtil.createWord(dataMap, "templates/entryform.ftl", uploadHead+entryFormFilesPath, fileOnlyName);