1. 程式人生 > >java使用freemarker模板匯出word(帶有合併單元格)文件

java使用freemarker模板匯出word(帶有合併單元格)文件

前言:最近要做一個匯出word功能,其實網上有很多的例子,但是我需要的是合併單元格的,可是查了好久都沒有自己想要的。研究了幾天其實挺簡單的,在這兒我就簡單的介紹一下吧!(此方法只是一種思路,借鑑者還有根據需求來具體寫程式碼)

一、準備工作

1、jar包:freemarker-2.3.20.jar

2、模板:word.ftl

2.1:這個word.ftl怎麼來?

首先準備一份要匯出的word.doc文件

這是一個事先寫好的一個word模板,我們需要做的就是把需要匯出的資料相應的插入${}到裡面(其實如果你瞭解freemarker就會明白的,${}是個佔位符,來放資料的,這裡不詳細介紹)。

如果下面的表格是固定的,比如像我們的課程表,那種是固定的,就特別簡單了。我要做的就是下面的表格需要根據資料的不同,實現合併單元格,先看一下生成以後的效果

大家可以看一下,前面三個格子是合併以後的,當然,如果後面兩個格子的資料只有一行,那麼也就是一行就行了。

2.2 將word.doc 轉化成word.xml

個人覺得,其實word就是一個xml檔案。開啟這個word,然後另存為xml格式,然後你再用office開啟這個xml,也是可開啟的。

然後用notepad(其他軟體隨意,不過最好可以格式化這個xml或者ftl檔案,否則你會頭炸的,啥都看不清)開啟這個

word.xml。然後你會發現,可能解析的時候,會把我們的"${}"這些給分開,沒事,你手動再把他們拼好就行了。

切記:拼接的時候,千萬要注意不要刪除或修改了裡面的什麼結構,後果自負(呵呵,其實就是格式錯誤了,就算你匯出成功,也不會開啟的,因為你已經損害了這個word)

2.3 完成這個xml以後,把這個word.xml 修改成字尾為.ftl的模板檔案,到此,這個模板就算完成了。

二、這裡先說根據模板word.ftl將匯出新的new.doc

1、其實這一步,網上多的是,我唯一有點不滿意的就是,它獲取模板的方法好像只有通過路徑來獲取,也許還有別的方法,歡迎知情者可以告訴我,哈哈!

2、先建立一個類(個人隨意,實現功能就行。)DocmentHandler.class

public class DocumentHandler {

	private Configuration configuration = null;
	
	public DocumentHandler(){
		configuration = new Configuration();
		configuration.setDefaultEncoding("UTF-8");
	}
	
	public byte[] createDocArea (Map<String, Object> dataMap ,String outFilePath,String fileName) throws Exception{
		//this.configuration.setClassForTemplateLoading(DocumentHandler.class, "D:\\");//第一種模板路徑
		System.out.println("---進入createDocArea---");
		this.configuration.setDirectoryForTemplateLoading(new File("/template/"));//第二種模板路徑
		Template t = null;
		File outFile = null;
		byte[] bFile = null;
		try {
			t = this.configuration.getTemplate(fileName,"UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		
		outFile = new File(outFilePath);
		Writer w = null;
		FileOutputStream fos = null;
		
		try {
			fos = new FileOutputStream(outFile);
			OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
			
			w = new BufferedWriter(osw);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		
		try {
			t.process(dataMap, w);
			if(outFile!=null){
				FileInputStream fis = new FileInputStream(outFile);
		         bFile = new byte[(int) outFile.length()];
		         fis.read(bFile);
		         fis.close();
			}
			System.out.println("--寫入完成---");
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}finally{
			w.close();
			fos.close();
		}
		return bFile;
	}
}
3、簡單介紹一下思路:它是通過這個configuration來獲取模板的,目前我就知道這兩種,一個是通過File,另一個種是通過Class,不過我試了一下,不過這兩種用哪一種,其實都是通過路徑來獲取的,然後它會根據在這個路徑下,來通過你給的模板名稱來找這個模板。所以這裡路徑下一定要有相應的模板。然後獲取模板以後,你再定義一個File,把封裝好的Map(這個map就是你要填充的資料)傳過來,它會通過流,結合模板,把資料寫入到你的新File中。至於你怎麼處理這個File,我就不管了。

三、封裝資料(關鍵

1、其實很好理解,填充模板資料的方式就是用key-value這個格式寫的(這個應該好理解吧!freemark),定義一個Map,map的key就是模板裡面的${key}這個屬性,一定要跟模板裡面的對應起來,value就是你要寫的資料;如果你不需要合併單元格,你就無腦的按照模板裡${key},對應的放資料就行,最後把map給第二步的匯出方法;

2、如果你的word裡需要迴圈的,那就再map裡放個list,至於模板裡怎麼迴圈,這就是涉及到freemarker的知識了,我就不解釋了,自己百度去;(哎,給個例子吧!)

一定要判斷你傳的這個是否為空,否則要是空的話,會報錯(它會用英文提示你,這個是空,你要判斷空的情況,利用<#if><#else></#if>,自己理解去吧!);

3、哈哈這兒才是重點:

        1、其實這個word合併單元格挺簡單的,就拿我上圖的那個結果來說,1到4(算上前面的那個序列號)個格子是需要合併的,後面的三個不需要。上圖是一個IP對應 後面五個單元格,所以其實它並不是一行,它是5行,(在這裡)ip是在第一行,然後第2到第4行的ip是空的。先理解這個!

2、合併需要的屬性值:<w:vMerge w:val='restart'/>和<w:vMerge/>

這倆才是控制合併單元格的罪魁禍首;

3、怎麼用?(看上圖)當迴圈第一行的時候,有IP、地域、重要攻擊、單位、時間;第二行,有空、空、空、單位、時間;第三行。。。。

4、然後在模板裡的第一行(也就是迴圈第一次的時候),新增<w:vMerge w:val='restart'/>(只在需要合併單元格的地方新增,看下圖)

簡單的解釋一下,一行的開始是以<w:tr w:rsidR="00806640" w:rsidRPr="00914E05" w:rsidTr="00806640">這個開始的,以</w:tr>結束的,這個是完整的一行,裡面的<w:tc>是代表一個格子,算是前面的序列號,我上圖也就 是6個<w:tc>放那個合併屬性的時候千萬別放錯地方了,我的是前四個(算上序列號)需要合並,所以我就在前四個<w:tc>裡放了這個;

然後再第二行(三行。。。迴圈)的時候,前面的ip是空的,這個時候要放<w:vMerge/>這個屬性,放的位置跟第一行的方法一樣,只是這個熟悉變了;

這樣的話就實現了合併單元格了;這樣第一個IP對應的單元格就完成了,第二個IP就迴圈著來唄!

4、以上就是一個完整的匯出過程了,當然,不管是封裝資料,還是合併單元格,我說的可能更多的只是個思路,具體怎麼封裝資料,怎麼想方設法的把資料放進模 板,仁者見者,智者見智吧!就到此為止吧,希望我說的大家可以看的明白,如果哪兒不明白的,或者哪兒寫的不對的,歡迎吐槽!

相關推薦

java使用freemarker模板匯出word帶有合併單元

前言:最近要做一個匯出word功能,其實網上有很多的例子,但是我需要的是合併單元格的,可是查了好久都沒有自己想要的。研究了幾天其實挺簡單的,在這兒我就簡單的介紹一下吧!(此方法只是一種思路,借鑑者還有根據需求來具體寫程式碼) 一、準備工作 1、jar包:freemarker

jxl匯出excel合併單元

Demo import java.io.*;   import jxl.*;   import jxl.format.UnderlineStyle;  import jxl.write.*;   publicclass CreateXLS {       public

java將資料匯出帶有合併單元的excel--jxls技術

        jxls技術可以生成各種樣式的報表,非常好用,深深地喜歡上了這個。說起用這個還是比較有意思的,當時專案有個匯出表格的功能,但是沒能合併單元格,客戶不是很滿意,當時專案中大家都說弄不了,我想著自己網上查查吧,就查到了這個,試了一下午完成了,很有成就感哪,哈哈。

Gitbook/Markdown中插入複雜合併單元的表格

由於Markdown語法本身不包含複雜表格的插入,因此gitbook也是不直接支援的,但是可以使用html語法來實現,一般的markdown編輯器都是支援html語法的。 複雜表格與簡單表格最大的差異有兩點:水平單元格的合併和縱向單元格的合併,通過html語法實現這兩個操作

HSSFWorkbook——匯出excel,動態合併單元

一 前言 開發中,對於匯出一個excel表格這樣的功能很常見,這裡談談我所知道的相關知識 二 需求  匯出某個套餐所關聯的所有專案的一個Excel表格 三 HSSFWorkbook //建立一個Excel檔案 HSSFWorkbook&

poi匯出excel時,合併單元後,求和不正確,即“假”合併

excel中所謂“真假”合併單元格 真合併:我們選擇一段連續的單元格,點選合併,這時候,EXCEL會提示如果合併只會顯示第一個單元格的資料,而且其他單元的的資料也會沒掉. 假合併:如果我們用一個已經合併的單元格,格式刷要合併的單元格,這時候沒有提示資料丟失的.事實上,這時候

java poi匯出Excel表,合併單元

其他參考文章: http://www.cnblogs.com/bmbm/archive/2011/12/08/2342261.html http://www.cnblogs.com/xuyuanjia/p/5886056.html 這是一個struts2的act

WPF使用 Polyline 元素動態繪製折線新增背景單元

前端程式碼 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; usin

C#中如何遍歷datagridview表格控制元件中的每一個格子每一個單元

如下程式碼,用兩個for迴圈即可,給每一個格子賦空值:  for (int i = 0; i < this.dgvHistoricDataMng.Rows.Count; i++)             {                 for (int j = 0

基於linux環境tcp網路程式設計線上英英詞典【2】

程式碼: client.c /************************************************************************* File Name: client.c Author: Young

Jxls匯出excel的若干方式總結十三-- 動態合併單元

可以看到程式碼中指定合併的部分現在已經顯示出了效果。 模板 List supplyAreaList = saBiz.getSupplyAreaById(supplyAreaId); SupplyArea sa = (SupplyArea) supplyAreaLis

利用模板匯出檔案之jacob利用word模板匯出word檔案Java2word

先下載jacob.jar包。解壓後將jacob.dll放到windows/system32下面或\jre\bin下面。將jacob.jar加入專案。 這樣專案的環境基本上搭建完成,接下來就是書寫相關的程式碼: /** * 傳入資料為HashMap物件,物件中的Key代表w

Laravel Excel實現Excel/CSV檔案匯入匯出的功能詳解合併單元,設定單元樣式

Laravel Excel實現Excel/CSV檔案匯入匯出(合併單元格,設定單元格樣式) 這篇文章主要給大家介紹了關於在Laravel中如何使用Laravel Excel實現Excel/CSV檔案匯入匯出功能的相關資料,文中通過示例程式碼介紹的非常詳細,對大

AspNet根據模板匯出Word

前言   最近的專案中需要應用到根據Wrod模板匯出文件的需求,一個很實用的功能。下面就來分享一下我的實現過程: 內容   環境:Asp.Net 新增:Aspose.Words Dll檔案的引用   步驟一:製作Wrod模板   通過編輯域來設定我

Excel 檔案匯出 js-xlsx合併單元的實現 vue

頁面資料如下圖: export default { data() { return { tableData: [],

AsposeWords操作表格合併單元(word已經有的table 列 合併 指定兩個單元 既可以橫向合併也可以縱向合併)-http://www.xiaoguo123.com/p/aspose_w

20180725 親測可以 xjh 強大的AsposeWords for java不僅支援建立表格,還支援合併單元格。今天就簡明扼要記錄下如何實現合併單元格。 大家可以完全套用本文提供的程式碼,只需要提供開始和結束的單元格即可實現合併,無需理解複雜的過程,真是簡潔好用啊。 此

table合併單元Jquery 外掛

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

ThinkPHP呼叫Excel類的基本用法設定合併單元,Sheet表標題,行高,列寬,字型,邊框,樣式

合併單元格+字型樣式 //合併單元格 $objPHPExcel->getActiveSheet(0)->mergeCells('A1:R1'); //為合併單元格新增標題 $objPHPExcel->setActiveSheetIndex(0)

java根據模板匯出pdf動態增加模板頁數

這兩天碰到了一個根據模板匯出pdf的需求,研究了幾天以後,發現網上的資料不太齊全,主要是沒找到既根據模板匯出,又可以動態增加頁數的例子。只能通過各種資料結合來實現這個需求了(其實是懶得看iText英文文件,這個以後得改過來)。 下面先來說下pdf匯出主要的兩種方

使用POI匯出Word含表格的實現方式及操作Word的工具類

轉載請註明出處:https://www.cnblogs.com/sun-flower1314/p/10128796.html  本篇是關於利用Apache 的POI匯出Word的實現步驟。採用XWPFDocument匯出Word,結構和樣式完全由程式碼控制,操作起來還是非常的不太方便,只能夠建立簡