通過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中 形式的空格
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(" ");
Pattern p = Pattern.compile(" ", 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(" ", "`");
}else{
/*for(int j = 0; j < 5; j++){
nodeText = nodeText.replace(" ", "`");
}*/
nodeText = nodeText.replaceAll(" ", "`");
}
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模板,使用jsoup將html轉換為word,包含圖片
實現思路: 一、製作模板 1、在word中無非三種格式,文字、圖片、表格,目前我所涉及到的業務中只有這三個,其他情況沒涉及到沒研究,首先需要準備一個模板檔案,即xml格式的模板,通過開啟一個空白的word文件,另存為xml檔案,即可得到一個空白的word模板(可使用not
將PDF轉換為word,HTML,SVG,XPS並將其儲存為流
本文我們將演示如何通過呼叫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轉換為整型的10,10.5轉換為10
說明: 在實際的應用過程中,有的時候可能會遇到字串的10,需要將字串的10轉換為數字的10 在此記錄下,通過int函式轉換的過程。 操作過程: 1.將字串轉換為整型的10 >>> str1 = "10" #將一個字串的10賦給變數str1 >&g
基於Spire.PDF將HTML轉換為PDF
將HTML轉換為PDF幾乎與每個人或群體相關,因為PDF是安全分發或共享的最佳格式。那麼我們應該如何輕鬆地將html轉換為PDF並且安全地變得非常重要。線上HTML到PDF轉換器真的很方便,但可能會導致隱私洩露,這可能是致命的,特別是對於合作,公司和組織。一個合理的解決方案是我們可以自己定製html
iText – 使用Java將HTML轉換為PDF
iText “XML Worker”允許開發人員以一種程式設計師友好的方式將XML檔案轉換成PDF檔案。iText還可以將包含CSS樣式的HTML轉換為PDF格式的文件。 目標: 實現如何利用iText Java庫將HTML檔案轉換成PDF文件?
JAVA常用API或程式設計工具001---ITEXT把html轉換成pdf的jar包,使用Java將HTML轉換為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
PHP將HTML轉換成各種格式圖片或PDF
安裝軟體清單 libwkhtmltox linux下的webkit核心 phpwkhtmltox php擴充套件,可呼叫webkit核心將網頁轉換成各種格式圖片或者pdf font-chinese 中文字型 msyh,Consolas 字型(優雅字型)
C#關於iTextSharp將html轉換為pdf不支援中文問題
使用iTextSharp的XMLWorker來解析帶html標籤的文字修改iTextSharp\iTextSharp\textFontFactoryImp.cs中的public virtual int RegisterDirectories()方法使其掃描自己所需要的中文字
java將xml解析,然後將其轉換為json格式(①)
java將xml裡面的內容解析的方法在我前面的文章:java解析xml檔案獲取xml裡面的資訊 有什麼問題可以給我留言!!! 下面就是如何將model轉換為json格式的內容: public class Student { private String
IE下用JavaScript將HTML匯出為Word、Pdf
最近升級公司內部系統發文章的功能,涉及到將文章內容匯出為html、word、pdf,系統多用於IE環境下,並且公司電腦都預裝了office,所以匯出暫時採用客戶端的方式。 頁面基本結構: <html> <hea
在html 中,將中文轉換為 html實體再輸出 即: 開頭的html實體編碼
將中文轉換為 html實體再輸出 編碼 /** * 可將中文轉換成 "&#" 開頭的html實體編碼 * * * @param str * @return */ public static String encode(String str) { cha
通過iText將html轉換成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