Velocity-2 樣例

ZhenFu_Tan發表於2020-09-30


前言

在這篇文章中,你將看生成一個 Word格式的目標檔案 的所有程式碼。當然,本例只是一個很小的實現。如果你有更好的實現方法,歡迎在評論區留言分享。
本文樣式待調整!!!


一、需求解讀

現在需要生成一個IT部資訊文件(資料純屬編造,如有雷同,純屬巧合)
資料純屬編造,如有雷同,純屬巧合

二、實現

1.準備模板檔案

第一步

編輯需求所給出的Word檔案,去除掉多餘的部分,只保留最基礎的內容,並將資料部分使用其他字元替代(任意字元,只要你自己能夠輕鬆識別出來即可)
在這裡插入圖片描述
可以看到,我將資料部分換成了[實體.屬性]

第二步

將word儲存為xml格式,這裡我另存為[DeptInfoTemplate.xml]

第三步

將xml格式的模板檔案的字尾直接修改為[vm],即[DeptInfoTemplate.vm]

第四步

這是最重要的一步哦

首先需要介紹兩個Velocity的語法
第一個:#foreach

	#foreach($item in $itemList)
		targetTempliteContent
	#end

意思是遍歷itemList中的每一個item,每一次遍歷均生成一段目標檔案型別的內容。
targetTempliteContent就是組成目標檔案的一部分,
即在本例中,目標檔案是word,那麼這一部分可以是

	<!-- 
		對於word的構成方式我也不是很懂,但是按我的理解,其實word也是跟html一樣,使用類似於<tag></tag>的標籤構成的
		<w:p></w:p>就是代表word中的一個段落 
	-->
	<w:p>
        <w:pPr>
          <w:rPr>
            <w:rFonts w:hint="default"/>
            <w:lang w:val="EN-US" w:fareast="ZH-CN"/>
          </w:rPr>
        </w:pPr>
        <w:r>
          <w:rPr>
            <w:rFonts w:hint="fareast"/>
            <w:lang w:val="EN-US" w:fareast="ZH-CN"/>
          </w:rPr>
          <w:t>合同編號:$item</w:t>
        </w:r>
      </w:p>

如果目標檔案是html,那麼targetTempliteContent可以是

<div>
	<p>$item</p>
</div>

也就是說 targetTempliteContent 是目標檔案中需要重複生成的那部分,比如本例需求中的員工花名冊的【行hang】。
第二個 $
是的,你沒看錯,就是一個 符號:$,使用他可以訪問velocity的上下文中的變數(業務資料)。
綜合這兩個語法
假設itemList = [‘胖大海’,‘程式猿’,‘單身狗’,‘矮矬窮’]
執行

	#foreach($item in $itemList)
		<div>
			<p>$item</p>
		</div>
	#end

那麼最終生成的檔案結構為:

	<div>
		<p>胖大海</p>
	</div>
	<div>
		<p>程式猿</p>
	</div>
	<div>
		<p>單身狗</p>
	</div>
	<div>
		<p>矮矬窮</p>
	</div>

看到這裡,我想,你已經知道本例中的模板檔案DeptInfoTemplate.vm需要怎麼處理了。值得一提的是,如果item是一個物件,那麼可以使用 $item.attrName來獲取item的屬性。

2.組裝資料

當模板檔案構造好後,你就可以根據模板檔案構造資料了。當然,你也可以先構造資料,然後根據資料的結構去調整模板。
你可以將要形成檔案的資料封裝在一個物件中,這個物件可以是你自己定義的資料模型,也可以直接使用java.util.Map,這裡我就不封裝模型了,直接使用Map物件。
程式碼如下:

	Map<String,Object> dept = new HashMap<String, Object>();//部門資訊
	List<Map<String,Object>> employeeList = new ArrayList<Map<String,Object>>();//員工列表
	List<Map<String,Object>> projList = new ArrayList<Map<String,Object>>();//專案列表
	employeeList = buildEmployeeList();
	projList = buildProjList();
	dept.put("name", "IT部");
	dept.put("employeeList", employeeList);
	dept.put("projList", projList);

3.目標檔案生成

	//根據你要形成目標檔案的資料構建上下文
	VelocityContext vc = new VelocityContext();
	vc.put("dept", dept);
	//初始化模板引擎		
	VelocityEngine ve = new VelocityEngine();
	ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
	ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
	ve.init();
	//初始化模板,
	String templateFilePath = "template/DeptInfoTemplate.vm";//模板檔案
	Template docTemplate = ve.getTemplate(templateFilePath, "UTF-8");
	File file = new File("D:"+File.separator+"demo"+File.separator+dept.get("name")+"資訊.doc");
	FileOutputStream outputStream = new FileOutputStream(file);

	OutputStreamWriter writer = new OutputStreamWriter(outputStream);
	docTemplate.merge(vc, writer);
	writer.flush();

執行後,如果一切正常,那麼你會在你指定的資料夾下看到目標檔案了。在這裡插入圖片描述
實際上,本例中我只告訴你了 【#foreach】 和 【$】的使用,實際上我還是用了另外一個語法,算是彩蛋吧,如果你找到了,歡迎在評論區留言哦。

另附:本例使用的Main.class以及DeptInfoTemplate.vm檔案(本人上傳的資源,現在估計還在稽核),Main.class沒有做很好的容錯處理,因為我覺得你,需要有自己除錯、找錯誤原因以及修復的能力。(好吧,實際上是我太懶了)

相關文章