1. 程式人生 > >使用freemarker模板生成Word文件和HTML

使用freemarker模板生成Word文件和HTML

注:該文件是參考某個大佬的資料,根據自己的需要修改的,具體是哪位大佬的忘了,如果作者自己看到需要加明出處的,請留言你的部落格地址

業務處理:

1,在業務中建立List<Map<String, Object>> data = new ArrayList<Map<String,Object>>(); 用來封裝需要生成文件的資料

2,把資料都封裝到集合後,再建立一個map,把封裝好資料的list,放進該map中

Map<String,Object> maps = new HashMap<>();

maps.put("name", XXX);//封裝資料

data.add(maps);//把封裝的map新增到集合

Map<String, Object> mapsData = new HashMap<String, Object>();
mapsData.put("maps", data);//把集合加入到最終map中

3,呼叫工具,生成文件

引數為:封裝好資料的map,是Word還是HTML,文件的名稱,和模板

WordUtil.exportMillCertificateWord(request,response,mapsData,"word",word_name,"banbenshixiang.ftl");

工具類:

public class WordUtil {
//配置資訊,程式碼本身寫的還是很可讀的,就不過多註解了
private static Configuration configuration = null;
//這裡注意的是利用WordUtils的類載入器動態獲得模板檔案的位置
//private static final String templateFolder = WordUtil.class.getClassLoader().getResource("../../").getPath() + "WEB-INF/templetes/";
private static String templateFolder ="";
//private static final String templateFolder = "H:/我的專案/lm/lm/web/src/main/webapp/WEB-INF/templates";
/*static {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
try {
if (templateFolder.startsWith("/")) {
templateFolder = templateFolder.substring(1, templateFolder.length()-1);
}
configuration.setDirectoryForTemplateLoading(new File(templateFolder));
} catch (IOException e) {
e.printStackTrace();
}
}*/

private WordUtil() {
throw new AssertionError();
}

public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map<String, Object> maps,
String type,String title,String ftlFile) throws IOException {
if (configuration == null) {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
}
try {
/*if (templateFolder.startsWith("/")) {
templateFolder = templateFolder.substring(1, templateFolder.length()-1);
}*/
templateFolder = request.getSession().getServletContext().getRealPath("/resources/template/word").toString();
configuration.setDirectoryForTemplateLoading(new File(templateFolder));
} catch (IOException e) {
e.printStackTrace();
}
Template freemarkerTemplate = configuration.getTemplate(ftlFile);
File file = null;
InputStream fin = null;
ServletOutputStream out = null;
try {
// 呼叫工具類的createDoc方法生成Word文件
file = createDoc(maps,freemarkerTemplate);
file.canWrite();
fin = new FileInputStream(file);

response.setCharacterEncoding("utf-8");
response.setContentType("application/msword");
// 設定瀏覽器以下載的方式處理該檔名
//String fileName = title+formatDateDetailTime(new Date()) + ".doc";
String fileName = "";
if (type.equals("word")) {
fileName = title + ".doc";
}else{
fileName = title + ".html";
}
response.setHeader("Content-Disposition", "attachment;filename="+new String(fileName.getBytes("gb2312"), "ISO8859-1"));

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<String, Object> maps, Template template) {
String name = "bumenxingzhengshenpiqingkuang.doc";
File f = new File(name);
Template t = template;
try {
// 這個地方不能使用FileWriter因為需要指定編碼型別否則生成的Word文件會因為有無法識別的編碼而無法開啟
//System.out.println(maps);
Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
t.process(maps, w);
w.close();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
return f;
}
public static String formatDateDetailTime(Date date){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(date);
}
}

呼叫工具後,以流的方式寫入到瀏覽器

 

生成Word時,文字內容無法自動換行,用\n和\r\n都沒用,系統裡的換行也沒用,解決辦法就是在需要換行的地方,新增字串<w:br/>,才能在生成好的Word裡看到換行

 

模板處理:

1,模板中固定好格式後,在需要動態填充資料的地方使用${資料欄位}進行佔位,有圖片的話自動轉換成base64字串.

 

 

2,模板固定好後,另存為一個xml格式的檔案,開啟該xml檔案,因為生成的xml檔案模板,裡面的一些元素生產的可能會把${XXX}給打亂,所以要手動修改下,把${  xml元素    xxx    xml元素}中的xml元素給刪了,否則導致報錯.

 

3,在動態的資料外,使用<#list maps as map>  </#list>給包裹起來,取值使用${map.xxx}

4,修改完成後,字尾名改為ftl,放到專案的指定目錄下

需要注意的是,生成的模板中都是xml元素和你的動態資料變數,可能會混在一起,需要你自己仔細的觀察修改,我自己生成Word時用的WPS的doc文件