1. 程式人生 > >通過freemarker模板,使用jsoup將html轉換為word,包含圖片

通過freemarker模板,使用jsoup將html轉換為word,包含圖片

實現思路:

一、製作模板

1、在word中無非三種格式,文字、圖片、表格,目前我所涉及到的業務中只有這三個,其他情況沒涉及到沒研究,首先需要準備一個模板檔案,即xml格式的模板,通過開啟一個空白的word文件,另存為xml檔案,即可得到一個空白的word模板(可使用notepad++工具開啟)

2、獲取到空白文件的模板後,再新建一個word,填充文字,再另存為xml,開啟並對比之前空白的模板之間的差異,可以找出新增文字後加了哪些程式碼。如果需要表格,則在空白文件加入加入表格,然後儲存為xml檔案開啟檢視程式碼,對比差異,可以知道具體的程式碼代表的意思。

3、圖片方面的處理,同樣是在空白文件中新增圖片,然後檢視xml程式碼,其中圖片是以base64形式出現的,在替換圖片的過程中,是需要將圖片的base64碼進行替換,所有的需要動態改變的資料,都使用freemarker標籤的形式替換,如果不瞭解的,自行去了解一下freemarker標籤的使用,具體的在xml中的程式碼的代表意思,可以到百度查詢。

二、填充模板

1、後臺使用jsoup解析HTML程式碼後,獲取html程式碼中的值,儲存到map中。文欄位落,圖片,表格,可分開處理。解析的HTML程式碼是通過百度UEditor生成的程式碼,如果是需要解析完整的正規的html程式碼,需要另外寫解析標籤的程式碼。

2、解析HTML時,可對應儲存HTML中標籤存在的屬性,對應xml中的屬性,通過實體來進行設定,遍歷標籤時,獲取實體屬性即可

3、填充模板儲存後的檔案仍然是xml格式的檔案,需要另外處理,將檔案另存為docx格式的word文件

實現程式碼:

注意:程式碼僅可以作為參考,即使完全複製,也不一定適合你,僅僅提供一個思路和參考,是否值得借鑑,需要自己評估,或者有更好的方法,歡迎留言評論一起交流

模板程式碼:(xml模板的程式碼,只貼出body中的程式碼)

<w:body>
		<wx:sect>
			<!-- 判斷第一部分是文欄位落,並遍歷第一部分的段落 -->
			<#if part1 == "paragraph">
			<#list paragraphList1 as paragraph>
			<w:p wsp:rsidR="0050577F" wsp:rsidRPr="00177379" wsp:rsidRDefault="00177379">
				<w:pPr>
					<w:jc w:val="${paragraph.align}"/>
					<w:rPr>
						<w:rFonts w:ascii="宋體" w:h-ansi="宋體" w:hint="fareast"/>
						<wx:font wx:val="宋體"/>
						<w:color w:val="${paragraph.color}"/>
						<#if paragraph_index==0>
						<w:sz w:val="30"/>
						<w:sz-cs w:val="30"/>
						<#else>
						<w:sz w:val="${paragraph.size}"/>
						<w:sz-cs w:val="${paragraph.size}"/>
						</#if>
					</w:rPr>
					<w:spacing w:line="${paragraph.lineHeight}" w:line-rule="auto"/>
				</w:pPr>
				<!-- 遍歷段落中的wr,每個wr可定義對應的文字屬性,如果內容不為空,則執行文字遍歷迴圈 -->
				<#list paragraph.wrList as wr>
				<#if wr.content??>
				<w:r>
					<w:rPr>
						<w:rFonts w:ascii="${wr.font}" w:fareast="${wr.font}" w:h-ansi="${wr.font}" w:hint="fareast"/>
						<wx:font wx:val="${wr.font}"/>
						<w:color w:val="${wr.color}"/>
						<#if paragraph_index==0>
						<w:sz w:val="30"/>
						<w:sz-cs w:val="30"/>
						<#else>
						<w:sz w:val="${paragraph.size}"/>
						<w:sz-cs w:val="${paragraph.size}"/>
						</#if>
						${wr.bold}
						${wr.tilt}
						${wr.underLine}
					</w:rPr>
					<w:t>${wr.content}</w:t>
				</w:r>
				</#if>
				<!-- 如果是圖片,則在wr上新增圖片 -->
				<#if wr.hasImg == 1>
				<#list wr.imgList as image>
				<w:r wsp:rsidRPr="006E22D7">
					<w:rPr>
						<w:noProof/>
					</w:rPr>
					<w:pict>
						<v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="
[email protected]
@[email protected]@[email protected]@[email protected]@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/> </v:shapetype> <w:binData w:name="wordml://${image.imgName}.png" xml:space="preserve">${image.imgBase64}</w:binData> <v:shape id="${image.imgId}" o:spid="_x0000_i1025" type="#_x0000_t75" style="width:${image.width}pt;height:${image.height}pt;visibility:visible;mso-wrap-style:square"> <v:imagedata src="wordml://${image.imgName}.png" o:title="${image.imgName}"/> </v:shape> </w:pict> </w:r> </#list> </#if> </#list> </w:p> </#list> </#if> <!-- 如果第一部分是表格,則填充表格 --> <#if part1 == "table"> <w:tbl> <w:tblPr> <w:tblW w:w="8522" w:type="dxa"/> <w:tblBorders> <w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:insideH w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:insideV w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> </w:tblBorders> <!-- 設定表格的對齊方式 --> <w:tblLook w:val="${table.tblLook}"/> </w:tblPr> <w:tblGrid> <!-- 表格列,定義的表格有多少列,則遍歷顯示多少個網格 --> <#list table.gridColList as gridCol> ${gridCol} </#list> </w:tblGrid> <!-- 遍歷表格中的行,tr --> <#list table.trList as tr> <w:tr wsp:rsidR="00616293" wsp:rsidRPr="00616293" wsp:rsidTr="00616293"> <w:trPr> <!-- 設定行高屬性 --> <w:trHeight w:val="${tr.height}"/> </w:trPr> <!-- 遍歷行中的列 --> <#list tr.tdList as td> <w:tc> <w:tcPr> <!-- 列寬屬性 --> <w:tcW w:w="${td.width}" w:type="dxa"/> <w:shd w:val="clear" w:color="auto" w:fill="auto"/> <w:tcBorders> ${td.top} ${td.right} ${td.bottom} ${td.left} </w:tcBorders> ${td.gridSpan} ${td.merge} </w:tcPr> <!-- 遍歷單元格中的段落文字 --> <#list td.paragraphList as paragraph> <w:p wsp:rsidR="0050577F" wsp:rsidRPr="00177379" wsp:rsidRDefault="00177379"> <w:pPr> <!-- 設定單元格中段落的屬性 --> <w:jc w:val="${paragraph.align}"/> <w:rPr> <w:rFonts w:ascii="宋體" w:h-ansi="宋體" w:hint="fareast"/> <wx:font wx:val="宋體"/> <w:color w:val="${paragraph.color}"/> <#if tr_index==0> <w:sz w:val="30"/> <w:sz-cs w:val="30"/> <#else> <w:sz w:val="${paragraph.size}"/> <w:sz-cs w:val="${paragraph.size}"/> </#if> </w:rPr> <w:spacing w:line="${paragraph.lineHeight}" w:line-rule="auto"/> </w:pPr> <!-- 遍歷段落中的wr --> <#list paragraph.wrList as wr> <!-- 如果內容不為空,則執行文字遍歷迴圈 --> <#if wr.content??> <w:r> <w:rPr> <w:rFonts w:ascii="${wr.font}" w:fareast="${wr.font}" w:h-ansi="${wr.font}" w:hint="fareast"/> <wx:font wx:val="${wr.font}"/> <w:color w:val="${wr.color}"/> <#if tr_index==0> <w:sz w:val="30"/> <w:sz-cs w:val="30"/> <#else> <w:sz w:val="${paragraph.size}"/> <w:sz-cs w:val="${paragraph.size}"/> </#if> ${wr.bold} ${wr.tilt} ${wr.underLine} </w:rPr> <w:t>${wr.content}</w:t> </w:r> </#if> <!-- 如果是圖片,則在wr上新增圖片 --> <#if wr.hasImg == 1> <!-- 遍歷圖片 --> <#list wr.imgList as image> <w:r wsp:rsidRPr="006E22D7"> <w:rPr> <w:noProof/> </w:rPr> <w:pict> <v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="[email protected]@[email protected]@[email protected]@[email protected]@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/> </v:shapetype> <!-- 設定圖片base64字元編碼 --> <w:binData w:name="wordml://${image.imgName}.png" xml:space="preserve">${image.imgBase64}</w:binData> <!-- 設定圖片屬性 --> <v:shape id="${image.imgId}" o:spid="_x0000_i1025" type="#_x0000_t75" style="width:${image.width}pt;height:${image.height}pt;visibility:visible;mso-wrap-style:square"> <v:imagedata src="wordml://${image.imgName}.png" o:title="${image.imgName}"/> </v:shape> </w:pict> </w:r> </#list> </#if> </#list> </w:p> </#list> </w:tc> </#list> </w:tr> </#list> </w:tbl> </#if> <!-- 判斷第二部分是文欄位落,並遍歷第一部分的段落 --> <#if part2 == "paragraph"> <#list paragraphList2 as paragraph> <w:p wsp:rsidR="0050577F" wsp:rsidRPr="00177379" wsp:rsidRDefault="00177379"> <w:pPr> <w:jc w:val="${paragraph.align}"/> <w:rPr> <w:rFonts w:ascii="宋體" w:h-ansi="宋體" w:hint="fareast"/> <wx:font wx:val="宋體"/> <w:color w:val="${paragraph.color}"/> <#if paragraph_index==0> <w:sz w:val="30"/> <w:sz-cs w:val="30"/> <#else> <w:sz w:val="${paragraph.size}"/> <w:sz-cs w:val="${paragraph.size}"/> </#if> </w:rPr> <w:spacing w:line="${paragraph.lineHeight}" w:line-rule="auto"/> </w:pPr> <!-- 遍歷段落中的wr,每個wr可定義對應的文字屬性,如果內容不為空,則執行文字遍歷迴圈 --> <#list paragraph.wrList as wr> <#if wr.content?? > <w:r> <w:rPr> <w:rFonts w:ascii="${wr.font}" w:fareast="${wr.font}" w:h-ansi="${wr.font}" w:hint="fareast"/> <wx:font wx:val="${wr.font}"/> <w:color w:val="${wr.color}"/> <#if paragraph_index==0> <w:sz w:val="30"/> <w:sz-cs w:val="30"/> <#else> <w:sz w:val="${paragraph.size}"/> <w:sz-cs w:val="${paragraph.size}"/> </#if> ${wr.bold} ${wr.tilt} ${wr.underLine} </w:rPr> <w:t>${wr.content}</w:t> </w:r> </#if> <!-- 如果是圖片,則在wr上新增圖片 --> <#if wr.hasImg == 1> <#list wr.imgList as image> <w:r wsp:rsidRPr="006E22D7"> <w:rPr> <w:noProof/> </w:rPr> <w:pict> <v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="[email protected]@[email protected]@[email protected]@[email protected]@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/> </v:shapetype> <w:binData w:name="wordml://${image.imgName}.png" xml:space="preserve">${image.imgBase64}</w:binData> <v:shape id="${image.imgId}" o:spid="_x0000_i1025" type="#_x0000_t75" style="width:${image.width}pt;height:${image.height}pt;visibility:visible;mso-wrap-style:square"> <v:imagedata src="wordml://${image.imgName}.png" o:title="${image.imgName}"/> </v:shape> </w:pict> </w:r> </#list> </#if> </#list> </w:p> </#list> </#if> <!-- 如果第二部分是表格,則填充表格 --> <#if part2 == "table"> <w:tbl> <w:tblPr> <w:tblW w:w="8522" w:type="dxa"/> <w:tblBorders> <w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:insideH w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:insideV w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> </w:tblBorders> <!-- 設定表格的對齊方式 --> <w:tblLook w:val="${table.tblLook}"/> </w:tblPr> <w:tblGrid> <!-- 表格列,定義的表格有多少列,則遍歷顯示多少個網格 --> <#list table.gridColList as gridCol> ${gridCol} </#list> </w:tblGrid> <!-- 遍歷表格中的行,tr --> <#list table.trList as tr> <w:tr wsp:rsidR="00616293" wsp:rsidRPr="00616293" wsp:rsidTr="00616293"> <w:trPr> <!-- 設定行高屬性 --> <w:trHeight w:val="${tr.height}"/> </w:trPr> <!-- 遍歷行中的列 --> <#list tr.tdList as td> <w:tc> <w:tcPr> <!-- 列寬屬性 --> <w:tcW w:w="${td.width}" w:type="dxa"/> <w:shd w:val="clear" w:color="auto" w:fill="auto"/> <w:tcBorders> ${td.top} ${td.right} ${td.bottom} ${td.left} </w:tcBorders> ${td.gridSpan} ${td.merge} </w:tcPr> <!-- 遍歷單元格中的段落文字 --> <#list td.paragraphList as paragraph> <w:p wsp:rsidR="0050577F" wsp:rsidRPr="00177379" wsp:rsidRDefault="00177379"> <w:pPr> <!-- 設定單元格中段落的屬性 --> <w:jc w:val="${paragraph.align}"/> <w:rPr> <w:rFonts w:ascii="宋體" w:h-ansi="宋體" w:hint="fareast"/> <wx:font wx:val="宋體"/> <w:color w:val="${paragraph.color}"/> <w:sz w:val="${paragraph.size}"/> <w:sz-cs w:val="${paragraph.size}"/> </w:rPr> <!-- 設定行間距 --> <w:spacing w:line="${paragraph.lineHeight}" w:line-rule="auto"/> </w:pPr> <!-- 遍歷段落中的wr --> <#list paragraph.wrList as wr> <!-- 如果內容不為空,則執行文字遍歷迴圈 --> <#if wr.content??> <w:r> <w:rPr> <w:rFonts w:ascii="${wr.font}" w:fareast="${wr.font}" w:h-ansi="${wr.font}" w:hint="fareast"/> <wx:font wx:val="${wr.font}"/> <w:color w:val="${wr.color}"/> <w:sz w:val="${wr.size}"/> <w:sz-cs w:val="${wr.size}"/> ${wr.bold} ${wr.tilt} ${wr.underLine} </w:rPr> <w:t>${wr.content}</w:t> </w:r> </#if> <!-- 如果是圖片,則在wr上新增圖片 --> <#if wr.hasImg == 1> <!-- 遍歷圖片 --> <#list wr.imgList as image> <w:r wsp:rsidRPr="006E22D7"> <w:rPr> <w:noProof/> </w:rPr> <w:pict> <v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="[email protected]@[email protected]@[email protected]@[email protected]@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/> </v:shapetype> <!-- 設定圖片base64字元編碼 --> <w:binData w:name="wordml://${image.imgName}.png" xml:space="preserve">${image.imgBase64}</w:binData> <!-- 設定圖片屬性 --> <v:shape id="${image.imgId}" o:spid="_x0000_i1025" type="#_x0000_t75" style="width:${image.width}pt;height:${image.height}pt;visibility:visible;mso-wrap-style:square"> <v:imagedata src="wordml://${image.imgName}.png" o:title="${image.imgName}"/> </v:shape> </w:pict> </w:r> </#list> </#if> </#list> </w:p> </#list> </w:tc> </#list> </w:tr> </#list> </w:tbl> </#if> <!-- 判斷第三部分是文欄位落,並遍歷第一部分的段落 --> <#if part3?? && part3 == "paragraph"> <#list paragraphList3 as paragraph> <w:p wsp:rsidR="0050577F" wsp:rsidRPr="00177379" wsp:rsidRDefault="00177379"> <w:pPr> <w:jc w:val="${paragraph.align}"/> <w:rPr> <w:rFonts w:ascii="宋體" w:h-ansi="宋體" w:hint="fareast"/> <wx:font wx:val="宋體"/> <w:color w:val="${paragraph.color}"/> <#if paragraph_index==0> <w:sz w:val="30"/> <w:sz-cs w:val="30"/> <#else> <w:sz w:val="${paragraph.size}"/> <w:sz-cs w:val="${paragraph.size}"/> </#if> </w:rPr> <w:spacing w:line="${paragraph.lineHeight}" w:line-rule="auto"/> </w:pPr> <!-- 遍歷段落中的wr,每個wr可定義對應的文字屬性,如果內容不為空,則執行文字遍歷迴圈 --> <#list paragraph.wrList as wr> <#if wr.content??> <w:r> <w:rPr> <w:rFonts w:ascii="${wr.font}" w:fareast="${wr.font}" w:h-ansi="${wr.font}" w:hint="fareast"/> <wx:font wx:val="${wr.font}"/> <w:color w:val="${wr.color}"/> <#if paragraph_index==0> <w:sz w:val="30"/> <w:sz-cs w:val="30"/> <#else> <w:sz w:val="${paragraph.size}"/> <w:sz-cs w:val="${paragraph.size}"/> </#if> ${wr.bold} ${wr.tilt} ${wr.underLine} </w:rPr> <w:t>${wr.content}</w:t> </w:r> </#if> <!-- 如果是圖片,則在wr上新增圖片 --> <#if wr.hasImg == 1> <#list wr.imgList as image> <w:r wsp:rsidRPr="006E22D7"> <w:rPr> <w:noProof/> </w:rPr> <w:pict> <v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="[email protected]@[email protected]@[email protected]@[email protected]@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/> </v:shapetype> <w:binData w:name="wordml://${image.imgName}.png" xml:space="preserve">${image.imgBase64}</w:binData> <v:shape id="${image.imgId}" o:spid="_x0000_i1025" type="#_x0000_t75" style="width:${image.width}pt;height:${image.height}pt;visibility:visible;mso-wrap-style:square"> <v:imagedata src="wordml://${image.imgName}.png" o:title="${image.imgName}"/> </v:shape> </w:pict> </w:r> </#list> </#if> </#list> </w:p> </#list> </#if> <w:sectPr wsp:rsidR="0050577F" wsp:rsidRPr="00177379"> <w:pgSz w:w="11906" w:h="16838"/> <w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0"/> <w:cols w:space="425"/> <w:docGrid w:type="lines" w:line-pitch="312"/> </w:sectPr> </wx:sect> </w:body>

解析html程式碼:

/**
 * 解析word
 * @Description: 
 *
 * @Date 2018年7月31日 
 * @author lxs
 * @version 2.1.4
 * 
 */
public class ParseWordUtil {
	public static Map<String, Object> getDataMap(Map<String, String> partMap, 
			Map<String, List<Map<String, String>>> sealMap, List<String> imgVariable) 
					throws IOException, BadElementException{
		// 填充word的資料
		Map<String,Object> dataMap = new HashMap<String, Object>();
		// 根據標籤的不連續,區分部分
		for(int i = 0; i < partMap.size(); i++){
			String partContent = partMap.get("part"+(i+1));
			List<WParagraph> paragraphList = null;
			Table table = new Table();
			// 獲取p標籤
			if(partContent.startsWith("<p")){
				// 傳入部分HTML程式碼,將內容解析為word文件的段落文字
				paragraphList = ParseWordUtil.getParagraphList(partContent, sealMap, imgVariable);
			} 
			// 獲取table標籤
			else if(partContent.startsWith("<table")){
				Document subDoc = Jsoup.parseBodyFragment(partContent);
				Elements e = subDoc.select("tr");
				// 獲取td列表的列數
				List<String> gridColList = ParseWordUtil.getGridColList(e);
				int cellSize = 0;
				if(gridColList != null && gridColList.size() > 0){
					cellSize = gridColList.size();
				}
				// 獲取tr列表
				List<Tr> trList = ParseWordUtil.getTrList(e, cellSize, sealMap, imgVariable);
				// 設定table屬性
				table.setGridColList(gridColList);
				table.setTrList(trList);
			}

			if(partContent.startsWith("<p")){
				dataMap.put("part"+(i+1), "paragraph");
				dataMap.put("paragraphList"+(i+1), paragraphList);
			} else if(partContent.startsWith("<table")){
				dataMap.put("part"+(i+1), "table");
				dataMap.put("table", table);
			}
		}
		return dataMap;
	}

	/**
	 * 獲取html部分內容,根據段落和表格區分部分
	 * @Description:
	 * @param childNodes
	 * @return 
	 * @author lxs
	 * @date 2018年7月31日
	 */
	public static Map<String, String> getPartMap(List<Node> childNodes){
		Map<String, String> partMap = new HashMap<String,String>();
		List<String> tarFlag = new ArrayList<String>();
		int changeFlag = 1;
		// 遍歷子標籤
		for (Node node : childNodes) {
			if(node.nodeName().trim().equals("#text")){
				continue;
			}
			tarFlag.add(node.nodeName());
			if(tarFlag.size() > 1){
				//判斷,最後一個是否和上一個標籤一致,不一致時,改變標誌+1
				if(!(tarFlag.get(tarFlag.size()-1).equals(tarFlag.get(tarFlag.size()-2)))){
					++ changeFlag;
				}
			}
			// 如果是p標籤
			if(node.toString().startsWith("<p")){
				if(partMap.get("part"+changeFlag) == null){
					partMap.put("part"+changeFlag, "");
				}
				partMap.put("part"+changeFlag, partMap.get("part"+changeFlag) + node.toString());
			}
			// 如果是table標籤
			else if(node.toString().startsWith("<table")){
				if(partMap.get("part"+changeFlag) == null){
					partMap.put("part"+changeFlag, "");
				}
				partMap.put("part"+changeFlag, partMap.get("part"+changeFlag) + node.toString());
			}
		}
		return partMap;
	}

	/**
	 * 傳入部分HTML標籤的程式碼,返回段落列表文字
	 * @Description:
	 * @param subHtml
	 * @return 
	 * @author lxs
	 * @throws IOException 
	 * @throws BadElementException 
	 * @date 2018年7月30日
	 */
	public static List<WParagraph> getParagraphList(String subHtml, 
			Map<String, List<Map<String, String>>> sealMap, List<String> imgVariable) 
					throws IOException, BadElementException{
		List<WParagraph> paragraphList = new ArrayList<WParagraph>();
		// 解析文件,獲取所有p標籤
		Document subDoc = Jsoup.parseBodyFragment(subHtml);
		List<Node> nodeP = subDoc.body().childNodes();
		// 遍歷所有p標籤
		for (Node node : nodeP) {
			if(node.nodeName().equals("#text")){
				continue;
			}
			WParagraph paragraph = new WParagraph();
			// 獲取p標籤的style屬性
			String pStyle = node.attr("style");
			if(pStyle != null && pStyle != ""){
				// 找到字型對齊方式,
				int alignStart = pStyle.indexOf("text-align:");
				int alignEnd = pStyle.indexOf(";", alignStart);
				String align = "";
				// 設定word段落的對齊方式
				if(alignStart > -1 && alignEnd > -1){
					align = pStyle.substring(alignStart+"text-align:".length(), alignEnd);
					paragraph.setAlign(align.trim());

				} else if(alignStart > -1 && alignEnd == -1){
					align = pStyle.substring(alignStart+"text-align:".length());
					paragraph.setAlign(align.trim());
				}
			}
			// 解析單個p標籤
			List<Wr> wrList = getWrList(node.toString(), sealMap, imgVariable);
			if(wrList == null || wrList.size() == 0){
				continue;
			}
			// word段落設定 w:r列表
			paragraph.setWrList(wrList);
			// 設定段落列表
			paragraphList.add(paragraph);
		}
		return paragraphList;
	} 

	/**
	 * 獲取列數量
	 * @Description:
	 * @param tdNum
	 * @return 
	 * @author lxs
	 * @date 2018年7月30日
	 */
	public static List<String> getGridColList(Elements e) {
		// 獲取表格中的列數
		int tdNum = 0;
		for (Element element : e) {
			int cellNums = 0;
			for (Node tdNode : element.childNodes()) {
				if(tdNode.nodeName().equals("#text")){
					continue;
				}
				cellNums ++;
			}
			if(cellNums >= tdNum){
				tdNum = cellNums;
				cellNums = 0;
			}
		}
		if(tdNum == 0){
			return null;
		}
		final int tableWidth = 9800;
		int colWidth = tableWidth/tdNum;
		List<String> gridColList = new ArrayList<String>();
		for (int i = 0; i < tdNum; i++) {
			gridColList.add("<w:gridCol w:w=\""+colWidth+"\"/>");
		}
		return gridColList;
	}

	/**
	 * 獲取tr列表
	 * @Description:
	 * @param e
	 * @param tdWidth
	 * @return 
	 * @author lxs
	 * @throws IOException 
	 * @throws BadElementException 
	 * @date 2018年7月30日
	 */
	public static List<Tr> getTrList(Elements e, int cellSize, Map<String, 
			List<Map<String, String>>> sealMap, List<String> imgVariable) 
					throws IOException, BadElementException {
		List<Tr> trList = new ArrayList<Tr>();
		// 遍歷表格tr
		for (Element element : e) {
			// 如果tr沒有子節點則不處理
			if(element.children().size() == 0){
				continue;
			}
			Tr tr = new Tr();
			// 獲取tr的td列表,並設定td列表
			List<Td> tdList = getTdList(element, cellSize, sealMap, imgVariable);
			tr.setTdList(tdList);
			// 設定tr列表
			trList.add(tr);
		}
		return trList;
	}

	/**
	 * 根據tr標籤,獲取一行的td列表
	 * @Description:
	 * @param element
	 * @return 
	 * @author lxs
	 * @throws IOException 
	 * @throws BadElementException 
	 * @date 2018年7月30日
	 */
	public static List<Td> getTdList(Element element, int cellSize, 
			Map<String, List<Map<String, String>>> sealMap, List<String> imgVariable) 
					throws IOException, BadElementException {
		List<Node> childTd = element.childNodes();
		List<Td> tdList = new ArrayList<Td>();
		int tdWidth = 9800/cellSize;
		// 遍歷tr中的td
		for (Node tdNode : childTd) {
			if(tdNode.nodeName().equals("#text")){
				continue;
			}
			Td td = new Td();
			// 設定單元格寬度
			td.setWidth(tdWidth+"");
			// 設定單元格合併屬性
			if(tdNode.hasAttr("colspan")){
				String colSpan = tdNode.attr("colspan");
				td.setGridSpan("<w:gridSpan w:val=\""+ colSpan +"\"/>");
			}
			String tdStyle = tdNode.attr("style");
			if(tdStyle != null && tdStyle != ""){
				String[] styleArr = tdStyle.split(";");
				for (String str : styleArr) {
					if(str.contains("border-top")){
						int index = str.indexOf(":");
						if(str.substring(index+1).trim().equals("none")){
							td.setTop("<w:top w:val=\"nil\"/>");
						}
					}
					if(str.contains("border-right")){
						int index = str.indexOf(":");
						if(str.substring(index+1).trim().equals("none")){
							td.setRight("<w:right w:val=\"nil\"/>");
						}
					}
					if(str.contains("border-bottom")){
						int index = str.indexOf(":");
						if(str.substring(index+1).trim().equals("none")){
							td.setBottom("<w:bottom w:val=\"nil\"/>");
						}
					}
					if(str.contains("border-left")){
						int index = str.indexOf(":");
						if(str.substring(index+1).trim().equals("none")){
							td.setLeft("<w:left w:val=\"nil\"/>");
						}
					}
				}
			}
			// 獲取td中的所有標籤
			List<Node> childP = tdNode.childNodes();
			// 如果td沒有p標籤
			Document spanDoc = Jsoup.parseBodyFragment(tdNode.toString());
			// 查詢td中的所有p標籤,不存在p標籤,則另外處理
			Elements pElement = spanDoc.select("p");
			if(pElement.size() == 0){
				List<WParagraph> subParagraphList = getSubParagraphList(childP, sealMap, imgVariable);
				td.setParagraphList(subParagraphList);
				tdList.add(td);
				continue;
			}
			
			List<WParagraph> paragraphList = getParagraphList(childP.toString(), sealMap, imgVariable);
			// td 段落列表
			td.setParagraphList(paragraphList);
			tdList.add(td);
		}
		// 行設定多個單元格列表
		return tdList;
	}

	/**
	 * 處理td中不存在p標籤的資料
	 * @Description:
	 * @param tdChilds td下的子標籤
	 * @param sealMap 圖片列表
	 * @param imgVariable 圖片變數
	 * @return 
	 * @author lxs
	 * @throws IOException 
	 * @throws BadElementException 
	 * @date 2018年8月2日
	 */
	public static List<WParagraph> getSubParagraphList(List<Node> tdChilds,
			Map<String, List<Map<String, String>>> sealMap,
			List<String> imgVariable) throws BadElementException, IOException {
		List<Wr> wrList = getWrList(tdChilds.toString(), sealMap, imgVariable);
		List<WParagraph> paragraphList = new ArrayList<WParagraph>();
		// 當獲取未獲取到其他標籤內容時,嘗試獲取td中的文字內容
		if(wrList.size() != 0){
			WParagraph paragraph  = new WParagraph();
			paragraph.setWrList(wrList);
			paragraphList.add(paragraph);
		}else{
			for (Node nodeStr : tdChilds) {
				if(!nodeStr.toString().equals("<br>")){
					Wr wr = new Wr();
					wr.setContent(nodeStr.toString());
					wrList.add(wr);
				}
			}
			WParagraph paragraph  = new WParagraph();
			paragraph.setWrList(wrList);
			paragraphList.add(paragraph);
		}
		return paragraphList;
	}
	
	/**
	 * 解析單個p標籤
	 * @Description:
	 * @param pText p標籤內容
	 * @param sealMap 圖片路徑列表
	 * @param imgVariable 圖片變數
	 * @return 
	 * @author lxs
	 * @throws IOException 
	 * @throws BadElementException 
	 * @date 2018年7月30日
	 */
	public static List<Wr> getWrList(String pText, 
			Map<String, List<Map<String, String>>> sealMap,
			List<String> imgVariable) 
					throws IOException, BadElementException{
		List<Wr> wrList = new ArrayList<Wr>();
		// 處理p標籤中,自身文字內容和標籤內容的順序問題
		String handleText = handleContextOfP(pText);
		Document spanDoc = Jsoup.parseBodyFragment(handleText);
		
		// p標籤自身存在內容
		Elements p = spanDoc.select("p");
		if(p.size() > 0){
			String pOwnText = p.get(0).ownText();
			// 清除轉義空格,製表符,換行,
			pOwnText = pOwnText.replaceAll("\\s*|\t|\r|\n", "");
			// 清除一般的空格
			pOwnText = pOwnText.replaceAll(" ", "");
			// 清除HTML中&nbsp;形式的空格
			pOwnText = pOwnText.replaceAll("[\\s\\u00A0]+", "");
			if(pOwnText.length() > 0){
				Wr wr = new Wr();
				wr.setContent(pOwnText);
				wrList.add(wr);
			}
		}
		// 查詢該標籤下的所有span標籤
		Elements spanElement = spanDoc.select("span");
		int spanElementSize = spanElement.size();
		// 存放span列表
		List<Element> spanList = new ArrayList<Element>();
		/** 遍歷獲取有所span標籤列表 **/
		for(int i = 0; i < spanElementSize; i++){
			int spanChilds = spanElement.get(i).childNodes().size();
			Element e = spanElement.get(i);
			// 如果標籤的內容為空,則跳過,不解析
			if(e.text().isEmpty() || e.ownText().length() == 0){
				continue;
			}
			// 如果沒有子標籤,則新增進span列表中
			if(spanChilds <= 1){
				spanList.add(e);
			} 
			// 如果存在子標籤
			else if(spanChilds > 1){
				// 先將自身內容取出
				String selfText = e.ownText();
				// 將所有子節點的內容清空,重新設定內容
				e.empty();
				e.text(selfText);
				spanList.add(e);
			}
		}
		/** 遍歷span列表,將span中的內容封裝到word文件的w:r中 **/
		for (Element span : spanList) {
			// 過濾span元素中,< 開頭和 > 結尾的所有內容
			// span元素的父級標籤
			String spanParentTag = span.parent().tagName();
			// 存在子標籤strong
			if(span.text().contains("<strong>")){
				List<Wr> subWrList = getSubSpan(span);
				wrList.addAll(subWrList);
				continue;
			}
			// w:r為圖片變數, 即span的內容為圖片的變數
			if(imgVariable.contains(span.text())){
				List<Wr> subWrList = getHasImgSpan(span, sealMap);
				wrList.addAll(subWrList);
				continue;
			}
			// 新建一個w:r物件
			Wr wr = new Wr();
			// 如果父標籤為strong,w:r設定加粗
			if(spanParentTag.equals("strong")){
				wr.setBold("<w:b/>");
			}
			//String str = handleStr(span.text());
			wr.setContent(span.text().replace("`", " "));
			wrList.add(wr);
		}
		// 過濾重複標籤
		for(int i = 0; i < wrList.size(); i++){
			if(i >= 1){
				if( wrList.get(i).getContent() != null && wrList.get(i).getContent().equals(wrList.get(i-1).getContent())){
					wrList.remove(i);
				}
			}
		}
		return wrList;
	}
	
	/**
	 * 處理存在html空格的字串
	 * @Description:
	 * @param text
	 * @return 
	 * @author lxs
	 * @date 2018年9月11日
	 */
	/*private static String handleStr(String text) {
		int index = text.indexOf("&nbsp;");
		Pattern p = Pattern.compile("&nbsp;", Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(text);
		int count = 0;
		while (m.find()) {
			count++;
		}
		StringBuffer sb = new StringBuffer();
		if(count > 6){
			sb.append(text.replace("`", ""));
			sb.insert(0, "  ");
		}else{
			sb.append(text.replace("`", ""));
			sb.insert(0, "       ");
		}
		return sb.toString();
	}*/

	/**
	 * 處理在p標籤中存在自身內容和標籤內容時,存在的內容順序混亂問題
	 * @Description:
	 * @param pText
	 * @return 
	 * @author lxs
	 * @date 2018年9月11日
	 */
	private static String handleContextOfP(String pText) {
		Document spanDoc = Jsoup.parseBodyFragment(pText);
		List<Node> childNodes = spanDoc.body().childNodes();
		List<Node> handleNodes = new ArrayList<Node>();
		for (Node node : childNodes) {
			// 若子節點以p標籤為開頭的,則處理,否則不處理
			if(node.toString().trim().startsWith("<p")){
				for (int i = 0; i< node.childNodeSize(); i++ ) {
					// 如果p的子節點是文字內容,不存在標籤,將文字內容用span包含
					if("#text".equals(node.childNode(i).nodeName())){
						if(node.childNode(i).toString().length() <= 0 ){
							continue;
						}
						Element e = new Element("span");
						String nodeText = node.childNode(i).toString().replaceAll("[\\s\\u00A0]+", " ");
						String[] strArr = nodeText.split(";");
						int count = 0;
						for (String str : strArr) {
							if(str.equals("nbsp")){
								count ++;
							}
						}
						if(count <= 6){
							nodeText = nodeText.replaceAll("&nbsp;", "`");
						}else{
							/*for(int j = 0; j < 5; j++){
								nodeText = nodeText.replace("&nbsp;", "`");
							}*/
							nodeText = nodeText.replaceAll("&nbsp;", "`");
						}
						e.appendText(nodeText);
						node.childNode(i).replaceWith(e);
						handleNodes.add(node);
						// 去除重複的資料
						for (int j = 0; j < handleNodes.size(); j++) {
							if(j > 0 && handleNodes.get(j).toString().equals(handleNodes.get(j - 1).toString())){
								handleNodes.remove(j);
								continue;
							}
						}
					}
				}
			} else{
				handleNodes.add(node);
			}
		}
		if(handleNodes.size() > 0){
			return handleNodes.toString();
		} else{
			return pText;
		}
	}

	/**
	 * 處理span元素中存在strong標籤的元素
	 * @Description:
	 * @param subSpanText
	 * @return 
	 * @author lxs
	 * @date 2018年8月1日
	 */
	public static List<Wr> getSubSpan(Element subSpanText){
		List<Wr> wrList = new ArrayList<Wr>();
		// 將文字內容,和strong標籤的內容分開儲存
		String spanText = subSpanText.text();
		List<String> spanTextList = new ArrayList<String>();
		int start = -1;
		int end = -1;
		while(true){
			start = spanText.indexOf("<strong>");
			end = spanText.indexOf("</strong>");
			if(start > -1 && end > -1){
				spanTextList.add(spanText.substring(0, start));
				spanTextList.add(spanText.substring(start, "</strong>".length()+end));
				spanText = spanText.substring("</strong>".length()+end);
			} else{
				spanTextList.add(spanText);
				break;
			}
		}
		// 遍歷span,生成wr
		for (String spanStr : spanTextList) {
			Wr wr = new Wr();
			// 如果存在strong標籤,則刪除標籤,保留內容
			if(spanStr.contains("<strong>")){
				wr.setBold("<w:b/>");
				int startIndex = -1;
				int endIndex = -1;
				while(true){
					String newEleText = "";
					startIndex = spanStr.indexOf("<");
					endIndex = spanStr.indexOf(">");
					if(startIndex > -1 && endIndex > -1){
						newEleText += spanStr.substring(0,startIndex);
						newEleText += spanStr.substring(endIndex+1);
					} else {
						break;
					}
					spanStr = newEleText;
				}
			}
			wr.setContent(spanStr);
			wrList.add(wr);
		}
		return wrList;
	}
	
	/**
	 * 處理span中的圖片變數
	 * @Description:
	 * @param element span標籤內容
	 * @param sealMap 圖片列表
	 * @return
	 * @throws BadElementException
	 * @throws IOException 
	 * @author lxs
	 * @date 2018年7月31日
	 */
	public static List<Wr> getHasImgSpan(Element element,  Map<String, List<Map<String, String>>> sealMap) throws BadElementException, IOException{
		List<Wr> wrList = new ArrayList<Wr>();
		Wr wr = new Wr();
		// 如果span的內容包含印章標籤則,設定圖片
		if(element.text().equals("${agentSeal}")){
			if(StringUtil.isEmpty(sealMap.get("agentSeal")) || sealMap.get("agentSeal").size() <= 0){
				wr.setContent("     ");
				wrList.add(wr);
			} else{
				wr.setHasImg(1);
				List<WImage> imgList = getImgList(sealMap.get("agentSeal"), "agentSeal");
				wr.setImgList(imgList);
				wrList.add(wr);
			}
		}
		if(element.text().equals("${reviewSeal}")){
			if(StringUtil.isEmpty(sealMap.get("reviewSeal")) || sealMap.get("reviewSeal").size() <= 0){
				wr.setContent("     ");
				wrList.add(wr);
			} else{
				wr.setHasImg(1);
				List<WImage> imgList = getImgList(sealMap.get("reviewSeal"), "reviewSeal");
				wr.setImgList(imgList);
				wrList.add(wr);
			}
		}
		if(element.text().equals("${approveSeal}")){
			if(StringUtil.isEmpty(sealMap.get("approveSeal")) || sealMap.get("approveSeal").size() <= 0){
				wr.setContent("     ");
				wrList.add(wr);
			}else{
				wr.setHasImg(1);
				List<WImage> imgList = getImgList(sealMap.get("approveSeal"), "approveSeal");
				wr.setImgList(imgList);
				wrList.add(wr);
			}
		}
		if(element.text().equals("${deptSeal}")){
			if(StringUtil.isEmpty(sealMap.get("deptSeal")) || sealMap.get("deptSeal").size() <= 0){
				wr.setContent("     ");
				wrList.add(wr);
			}else{
				wr.setHasImg(1);
				List<WImage> imgList = getImgList(sealMap.get("deptSeal"), "deptSeal", "120", "80");
				wr.setImgList(imgList);
				wrList.add(wr);
			}
		}
		if(element.text().equals("${companySeal}")){
			if(StringUtil.isEmpty(sealMap.get("company")) || sealMap.get("company").size() <= 0){
				wr.setContent("     ");
				wrList.add(wr);
			}else{
				wr.setHasImg(1);
				List<WImage> imgList = getImgList(sealMap.get("company"), "company", "120", "80");
				wr.setImgList(imgList);
				wrList.add(wr);
			}
		}
		return wrList;
	}

	/**
	 * 獲取圖片列表
	 * @Description:
	 * @param sealList
	 * @param imgName
	 * @return 
	 * @author lxs
	 * @throws IOException 
	 * @throws BadElementException 
	 * @date 2018年7月31日
	 */
	public static List<WImage> getImgList(List<Map<String,String>> sealList, String imgName) throws IOException, BadElementException{
		int sealLen = sealList.size();
		List<WImage> imgList = new ArrayList<WImage>();
		for(int i = 0; i< sealLen; i++){
			WImage img = new WImage();
			//Image image = Image.getInstance(sealList.get(i).get("sealPath"));
			// 個人章大小
			//img.setHeight(image.getHeight()+"");
			//img.setWidth(image.getHeight()+"");
			img.setHeight("30");
			img.setWidth("65");
			img.setImgId(imgName + "_" + i);
			img.setImgName(imgName + "_" + i);
			img.setImgBase64(ImageHandleUtil.getImgStr(sealList.get(i).get("sealPath")));
			imgList.add(img);
		}
		return imgList;
	}
	
	/**
	 * 獲取圖片列表
	 * @Description:
	 * @param sealList
	 * @param imgName
	 * @return 
	 * @author lxs
	 * @throws IOException 
	 * @throws BadElementException 
	 * @date 2018年7月31日
	 */
	public static List<WImage> getImgList(List<Map<String,String>> sealList, String imgName, String width, String height) throws IOException, BadElementException{
		int sealLen = sealList.size();
		List<WImage> imgList = new ArrayList<WImage>();
		for(int i = 0; i< sealLen; i++){
			WImage img = new WImage();
			Image image = Image.getInstance(sealList.get(i).get("sealPath"));
			// 部門章
			//img.setHeight(image.getHeight()+"");
			//img.setWidth(image.getHeight()+"");
			float imgHeight= image.getHeight();
			float imgWidth = image.getWidth();
			float resNumber = (imgHeight - imgWidth) > 0 ? (imgHeight - imgWidth) : -(imgHeight - imgWidth);
			if(resNumber > 20){
				img.setHeight(height);
				img.setWidth(width);
			} else{
				img.setHeight("120");
				img.setWidth("120");
			}
			img.setImgId(imgName + "_" + i);
			img.setImgName(imgName + "_" + i);
			img.setImgBase64(ImageHandleUtil.getImgStr(sealList.get(i).get("sealPath")));
			imgList.add(img);
		}
		return imgList;
	}
}

其他的一些實體類以及屬性,根據自己的需求建立:

使用到的工具類:

1、圖片轉base64

2、StringUtil的字串非空判斷:

使用到的包:

1、jsoup

2、itextpdf

該功能主要是通過前臺使用百度UEditor富文字編輯器,編輯模板並新增變數,然後儲存,後臺通過解析儲存的模板原始碼,替換變數。填充模板來實現的,如果有發現問題,或者有建議的,歡迎指出,感激不盡,有問題的也可以留言評論。

相關推薦

通過freemarker模板使用jsouphtml轉換word,包含圖片

實現思路: 一、製作模板 1、在word中無非三種格式,文字、圖片、表格,目前我所涉及到的業務中只有這三個,其他情況沒涉及到沒研究,首先需要準備一個模板檔案,即xml格式的模板,通過開啟一個空白的word文件,另存為xml檔案,即可得到一個空白的word模板(可使用not

PDF轉換wordHTMLSVGXPS並其儲存

本文我們將演示如何通過呼叫Spire.PDF提供的方法PdfDocument.SaveToStream()將PDF頁面轉換為HTML,Word,SVG,XPS,PDF並將它們儲存為流。從Spire.PDF版本4.3開始,它新支援轉換定義範圍的PDF頁面並將其儲存為流。 將PDF儲存為流 步驟

C# HTML 轉換圖片或 PDF

ont gif completed 字段 sed pad cli 滾動條 lose 首先是把 HTML 轉換為圖片。 public partial class Form1 : Form { public Form1() {

get傳輸時加號+ 轉換空格

技術 傳輸 解決 ima ges png 前端 後端 blog 解決辦法: 前端: 替換加號為 ‘%2B’, 後端: 直接接收即可。 get傳輸時,會將加號+ 轉換為空格

python中如何字串轉換數字(數字轉換整型)字串的10轉換整型的1010.5轉換10

說明:   在實際的應用過程中,有的時候可能會遇到字串的10,需要將字串的10轉換為數字的10   在此記錄下,通過int函式轉換的過程。 操作過程: 1.將字串轉換為整型的10 >>> str1 = "10" #將一個字串的10賦給變數str1 >&g

基於Spire.PDFHTML轉換PDF

將HTML轉換為PDF幾乎與每個人或群體相關,因為PDF是安全分發或共享的最佳格式。那麼我們應該如何輕鬆地將html轉換為PDF並且安全地變得非常重要。線上HTML到PDF轉換器真的很方便,但可能會導致隱私洩露,這可能是致命的,特別是對於合作,公司和組織。一個合理的解決方案是我們可以自己定製html

iText – 使用JavaHTML轉換PDF

iText “XML Worker”允許開發人員以一種程式設計師友好的方式將XML檔案轉換成PDF檔案。iText還可以將包含CSS樣式的HTML轉換為PDF格式的文件。 目標: 實現如何利用iText Java庫將HTML檔案轉換成PDF文件?

JAVA常用API或程式設計工具001---ITEXT把html轉換成pdf的jar包,使用JavaHTML轉換PDF

iText “XML Worker”允許開發人員以一種程式設計師友好的方式將XML檔案轉換成PDF檔案。iText還可以將包含CSS樣式的HTML轉換為PDF格式的文件。 目標: 實現如何利用iText Java庫將HTML檔案轉換成PDF文件? Environment &

組合語言學習之路(7)------------輸入10進位制數轉換2進位制數,存放在ax中轉換ASCII碼並輸出

data segment        inf1 db "please input a number(1-361):$"        ibuf db 7,0,6 dup(0)        obuf db 6 dup(0)        data ends        c

如何檢視張量tensor轉換numpy資料

在tensorflow 中一般資料都是用tensor來表示,而在python 中一般是用numpy包,然而有時候需要列印變數的資料,可用以下方法來列印: 一、 import tensorflow as tf a = tf.constant(2.1) #定義tensor常量 with tf

Python HTML轉換TXT

CODE: #!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-9-5 @author: guaguastd @name: html_to_text.py ''' from login impor

如何HTML轉換純文字格式Text

可以完成HTML到Text的轉換,但是不能將表格轉換成HTML這是一個大困難。到現在都沒有找到一個比較好的實現。 HtmlAgilityPack.dll 這兒是一個用perl實現的將html表格轉換成純文字。 http://www.vbforums.com/sho

html2text: HTML 轉換 Markdown 格式文字

安裝: pip install html2text Option Description –version Show program’s version numb

PHPHTML轉換成各種格式圖片或PDF

安裝軟體清單 libwkhtmltox linux下的webkit核心 phpwkhtmltox php擴充套件,可呼叫webkit核心將網頁轉換成各種格式圖片或者pdf font-chinese 中文字型 msyh,Consolas 字型(優雅字型)

C#關於iTextSharphtml轉換pdf不支援中文問題

使用iTextSharp的XMLWorker來解析帶html標籤的文字修改iTextSharp\iTextSharp\textFontFactoryImp.cs中的public virtual int RegisterDirectories()方法使其掃描自己所需要的中文字

javaxml解析然後轉換json格式(①)

java將xml裡面的內容解析的方法在我前面的文章:java解析xml檔案獲取xml裡面的資訊 有什麼問題可以給我留言!!! 下面就是如何將model轉換為json格式的內容: public class Student { private String

IE下用JavaScriptHTML匯出Word、Pdf

       最近升級公司內部系統發文章的功能,涉及到將文章內容匯出為html、word、pdf,系統多用於IE環境下,並且公司電腦都預裝了office,所以匯出暫時採用客戶端的方式。        頁面基本結構:        <html> <hea

html中文轉換 html實體再輸出 即: 開頭的html實體編碼

將中文轉換為 html實體再輸出 編碼 /** * 可將中文轉換成 "&#" 開頭的html實體編碼 * * * @param str * @return */ public static String encode(String str) { cha

通過iTexthtml轉換成pdf中文亂碼問題

這個問題今天除錯了5、6小時,真是極度鬱悶,不過最終通過除錯iText原始碼以及查資料還是搞定。首先參考我搜到到的一點關鍵資訊:  這是由編碼問題引起的。XML標準規定,XML分析器必須支援“UTF-8”和“UTF-16”編碼,而且必須能夠自動區分這兩種編碼的檔案,對於其他編碼(包括常用的中文編碼“GB23

通過泛型string轉換指定類型

quest model urn grid hyperlink ror return exceptio ngs Generic TryParse You should use the TypeDescriptor class: public static T Conv