1. 程式人生 > >java匯出word文件,動態隨機插入多張圖片(web端可下載)

java匯出word文件,動態隨機插入多張圖片(web端可下載)

工具:freemarker
有關freemarker的載入方式可參照
https://www.cnblogs.com/qiaoqiaodi/p/7082878.html

1、建立模板
  網上有很多建立模板的文章可參考,大概可概括為以下幾點
  ①建立word文件,根據自己的需求做好word內容的樣式
  ②把word文件中,需要動態插入的內容替換為英文名稱


  ③關鍵的一步,word文件另存為,儲存格式為Word XML文件


  ④在另存為的xml文件中,把②中替換的英文名稱替換為${xxx},作為模板引數


  ⑤更改xml文件字尾,改為.ftl,模板建立完成。

2、編輯引數
     引數存放在map中,模板裡所有的引數都要存在map中,map裡的引數可以比模板引數多,但不能少
     Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("title", “ddddd”);

3、匯出word(web端下載功能實現)

 try {
            
            // 獲取模板
            configuration.setClassForTemplateLoading(this.getClass(), 模板path);
            
            Template wordTemplate = configuration.getTemplate(template);
            
            // 檔名
            String fileNameEncoded = URLEncoder.encode(fileName, "utf-8");
            
            // 前端響應(HttpServletResponse)
            response.setContentType("application/vnd.ms-word");
            response.setHeader("Content-disposition", "attachment;filename=" + fileNameEncoded);
            
            // 寫入資料
            Writer writer = response.getWriter();
            wordTemplate.process(dataMap, writer);
            
            writer.flush();
            writer.close();
            
        } catch (Exception e) {
            e.printStackTrace();
        } 

4、圖片的匯出
   網上有很多匯出圖片的方式,但都是匯出到固定的引數,固定的位置。
   現在,要實現在某個區域,既要匯出文字,又要匯出圖片,而且圖片是根據條件,
   需要圖片的時候就匯出,不需要就不匯出圖片,實現圖片的動態匯出。

 ①實現這個功能,要先知道帶圖片word模板的結構,也就是xml結構
   格式化xml模板後,可以找與圖片相關的xml內容有以下幾個地方
       一、Relationships

<pkg:part pkg:name="/word/_rels/document.xml.rels"
		pkg:contentType="application/vnd.openxmlformats-package.relationships+xml"
		pkg:padding="256">
		<pkg:xmlData>
			<Relationships
				xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
				<Relationship Id="rId5"
					Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable"
					Target="fontTable.xml" />
				<Relationship Id="rId4"
					Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
					Target="media/image1.jpeg" />
			</Relationships>
		</pkg:xmlData>
	</pkg:part>

 二、drawing,也就是圖片所在word中的位置

<w:drawing>
	<wp:inline distT="0" distB="0" distL="0" distR="0">
		<wp:extent cx="5238750" cy="2944195" />
		<wp:effectExtent l="19050" t="0" r="0" b="0" />
		<wp:docPr id="1" name="圖片 0" descr="t0121e99944f83e0638.jpg" />
		<wp:cNvGraphicFramePr>
			<a:graphicFrameLocks noChangeAspect="1"
				xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" />
		</wp:cNvGraphicFramePr>
		<a:graphic
			xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
			<a:graphicData
				uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
				<pic:pic
					xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
					<pic:nvPicPr>
						<pic:cNvPr id="0" name="t0121e99944f83e0638.jpg" />
						<pic:cNvPicPr />
					</pic:nvPicPr>
					<pic:blipFill>
						<a:blip r:embed="rId4" />
						<a:stretch>
                                                                                     <a:fillRect />
						</a:stretch>
					</pic:blipFill>
					<pic:spPr>
						<a:xfrm>
							<a:off x="0" y="0" />
							<a:ext cx="5238750" cy="2944195" />
						</a:xfrm>
						<a:prstGeom prst="rect">
							<a:avLst />
						</a:prstGeom>
					</pic:spPr>
				</pic:pic>
			</a:graphicData>
		</a:graphic>
	</wp:inline>
</w:drawing>

三、圖片base64位元組碼存放的位置

<pkg:part pkg:name="/word/media/image1.jpeg" pkg:contentType="image/jpeg"
		pkg:compression="store">
		<pkg:binaryData>/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEP
			................................
		</pkg:binaryData>
	</pkg:part>

根據以上三段內容,可以看出,一個圖片在word中正常顯示,離不開以上三段xml。所以,實現動態匯出圖片。就要在程式碼中手動編輯三段xml,作為引數放在模板中。

     以上三段內容的關係如下:
     drawing中【<a:blip r:embed="rId4" />】對應Relationships中的【<Relationship Id="rId4"】
     Relationships中的【<Relationship Id="rId4"】的【Target="media/image1.jpeg" />】對應base64位元組碼的【<pkg:part pkg:name="/word/media/image1.jpeg"】
     
     程式碼開發的時候,需要動態的改變【r:embed】、【Target】的值,一張圖片對應一個值。

     匯出圖片的時候,可能需要對圖片進行壓縮,可以參考https://www.cnblogs.com/miskis/p/5500822.html