通过xml方式根据word模板导出word
生活随笔
收集整理的這篇文章主要介紹了
通过xml方式根据word模板导出word
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1 . 實(shí)現(xiàn)代碼
package com.base.pf.common.util;import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.Map; import java.util.Set;import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import org.apache.axis.encoding.Base64;import com.base.pf.base.util.PropertiesMgr; import com.base.pf.base.util.StringUtils;/*** 導(dǎo)出WORD* * @author ZHEN.L* @date 2014.09.23* @date 2014.11.05* */ public class WordUtils {/*** 轉(zhuǎn)換PDF格式*/public static final String WORD_2_PDF = "Word.pdf";/*** word導(dǎo)出標(biāo)記*/public static final String WORD_EXP_TAG = "Word.exp";/*** word導(dǎo)出值*/public static final String WORD_EXP_TAG_VALUE = "word";/*** 模板名稱標(biāo)記*/public static final String WORD_TEMPLATE_NAME = "Word.fileName";/*** 模板名稱標(biāo)記*/public static final String WORD_FILE_NAME = "fileName";/*** 模板名稱標(biāo)記:動(dòng)態(tài)字段*/public static final String WORD_FILE_NAME_FIELD = "FieldfileName";// 模板路徑protected static final String WORD_TEMPLATE_PATH = "\\page\\project\\template_word\\";/*** word中換行:需要將word中\(zhòng)r\n轉(zhuǎn)回為以下字符串 <w:spacing w:line="240" w:line-rule="auto"* /> 240為單倍行距,360為1.5倍行距*/protected static final String LINE_FEED = "</w:t></w:r></w:p><w:p wsp:rsidR=\"004C3B63\" wsp:rsidRDefault=\"004C3B63\" wsp:rsidP=\"00302FB9\"><w:pPr><w:spacing w:line=\"340\" w:line-rule=\"auto\" /><w:rPr><w:rFonts w:ascii=\"宋體\" w:h-ansi=\"宋體\"/><wx:font wx:val=\"宋體\"/><w:sz w:val=\"24\"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii=\"宋體\" w:h-ansi=\"宋體\" w:hint=\"fareast\"/><wx:font wx:val=\"宋體\"/><w:sz w:val=\"24\"/></w:rPr><w:t> ";protected static final String PDF_PATH = PropertiesMgr.getValue("exp_word_pdf_path") + "/";/*** 導(dǎo)出word* * @param response*/public synchronized static String exp(HttpServletRequest request,HttpServletResponse response, Object obj) {String xml = "";String PDF = request.getParameter(WORD_2_PDF);Map map = BeanToMapUtils.convertBean(obj);String templatePath = request.getServletContext().getRealPath("/")+ WORD_TEMPLATE_PATH;String templateName = request.getParameter(WORD_TEMPLATE_NAME);// 模板名稱,程序中獲取,通過DTO傳遞過來if (map.get("templateName") != null) {templateName = String.valueOf(map.get("templateName"));}File file = new File(templatePath + templateName);String fileName = request.getParameter(WORD_FILE_NAME);String fieldFileName = request.getParameter(WORD_FILE_NAME_FIELD);if (!file.exists()) {throw new NullPointerException("模板不存在!");}OutputStream os = null;BufferedReader br = null;try {br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));String buf = null;while ((buf = br.readLine()) != null) {xml += buf;}// ContactDtoT dto = new ContactDtoT();// if (!(obj instanceof Map))// BeanUtils.copyProperties(obj, dto);if (!StringUtils.isEmpty(fieldFileName)) {String temp = String.valueOf(map.get(fieldFileName));if (!StringUtils.isEmpty(temp)) {fileName = temp.trim() + fileName;}}xml = replace(xml, map);if (!"word".equalsIgnoreCase(PDF)) {File pdfFile = new File(PDF_PATH);if (!pdfFile.exists()) {pdfFile.mkdirs();}OutputStream localOs = new FileOutputStream(new File(PDF_PATH+ fileName + ".doc"));localOs.write(xml.getBytes("UTF-8"));PDFUtils.download(request, response, PDF_PATH + fileName+ ".doc");return null;}response.setContentType("application/msword,charset=UTF-8");response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(fileName + ".doc", "UTF-8"));os = response.getOutputStream();os.write(xml.getBytes("UTF-8"));} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {close(br, os);}return null;}// 將文件,轉(zhuǎn)換成BASE64protected static String getBASE64(String path) {// path = "d:/1.jpg";String base64 = "";File file = new File(path);FileInputStream fis = null;ByteArrayOutputStream bos = null;try {fis = new FileInputStream(file);bos = new ByteArrayOutputStream(1000);byte[] bytes = new byte[1024];while ((fis.read(bytes)) != -1) {bos.write(bytes);}base64 = Base64.encode(bos.toByteArray());} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {close(fis, bos);}return base64;}// 替換xml中字符protected static String replace(String xml, Map map) {Integer pWidth = 0, pHeight = 0; // 印章高度、寬度Set set = map.keySet();int photoIndex = 0; // 圖片序號(hào)標(biāo)記Iterator its = set.iterator();String key, value, tagKey, photoXml; // 圖片部分XMLwhile (its.hasNext()) {try {key = StringUtils.withSpaceReplaceNull(its.next());tagKey = "${" + key + "}";value = StringUtils.withSpaceReplaceNull(map.get(key));if (key.startsWith("photo_")) {photoIndex++;ImageDto imageDto = readImageInfo(value);// 設(shè)計(jì)思想: 首先將XML中圖片標(biāo)記${key}替換為word圖片對(duì)應(yīng)的XML;// 第二,將${photo_tag}圖片(電子印章)替換為對(duì)應(yīng)的${key}值,再將${key}替換為base64,// 公司公章:大部分長(zhǎng)度4.2cm,個(gè)別長(zhǎng)度3.8if ("photo_superName".equalsIgnoreCase(key)|| "photo_super".equalsIgnoreCase(key)) {// 圖片位置String pict_position_left = StringUtils.withSpaceReplaceNull(map.get("pict_position_left"));String pict_position_top = StringUtils.withSpaceReplaceNull(map.get("pict_position_top"));pict_position_left = "".equals(pict_position_left) ? "0": pict_position_left;pict_position_top = "".equals(pict_position_top) ? "-47": pict_position_top;photoXml = IMG_UP.replace("${pict_index}", // 替換圖片序列號(hào)String.valueOf(photoIndex));photoXml = photoXml.replace("${pict_position_left}",pict_position_left); // 替換圖片左側(cè)位置photoXml = photoXml.replace("${pict_position_top}",pict_position_top); // 替換圖片上部位置// 像素和厘米之間的換算是需要知道圖片的分辨率的。通常設(shè)計(jì)網(wǎng)頁的時(shí)候,圖片的分辨率一般都是用72dpi的,// 即72像素/英寸,由于1英寸= 2.54厘米,所以在設(shè)計(jì)網(wǎng)頁的時(shí)候,一般1厘米約為28像素imageDto.getWidth();photoXml = photoXml.replace("${pict_width}",getpWidth(key, null, imageDto.getWidth())); // 替換圖片寬度photoXml = photoXml.replace("${pict_height}",getpHeight(key, null, imageDto.getHeight())); // 替換圖片高度photoXml = photoXml.replace("${pict_tag}", tagKey);xml = xml.replace(tagKey, photoXml);// 個(gè)人簽章:個(gè)人簽名(高1.8cm,寬待定)、執(zhí)業(yè)資格章(高3cm,寬4.5cm)} else if ("photo_engineer".equalsIgnoreCase(key)|| "photo_chief".equalsIgnoreCase(key)) {String pict_position_left = StringUtils.withSpaceReplaceNull(map.get("pict_position_left_personal"));String pict_position_top = StringUtils.withSpaceReplaceNull(map.get("pict_position_top_personal"));pict_position_top = "".equals(pict_position_top) ? "0": pict_position_top;pict_position_left = "".equals(pict_position_left) ? "0": pict_position_left;photoXml = IMG_UP.replace("${pict_index}",String.valueOf(photoIndex));photoXml = photoXml.replace("${pict_position_left}",pict_position_left); // 替換圖片左側(cè)位置photoXml = photoXml.replace("${pict_position_top}",pict_position_top); // 替換圖片上部位置photoXml = photoXml.replace("${pict_width}",getpWidth(key, map.get("personalSealType"),imageDto.getWidth())); // 替換圖片寬度photoXml = photoXml.replace("${pict_height}",getpHeight(key, map.get("personalSealType"),imageDto.getHeight())); // 替換圖片高度photoXml = photoXml.replace("${pict_tag}", tagKey);xml = xml.replace(tagKey, photoXml);}xml = xml.replace(tagKey, imageDto.getBase64());} else {value = value.replace("\r\n", LINE_FEED);xml = xml.replace(tagKey, value);}} catch (Exception e) {e.printStackTrace();}}String date = new SimpleDateFormat("yyyy 年 MM 月 dd 日").format(new Date());xml = xml.replace("${date}", date);xml = xml.replace("${photo_}", "");xml = xml.replace("${photo_superName}", "");xml = xml.replace("${photo_super}", "");xml = xml.replace("${photo_engineer}", "");xml = xml.replace("${photo_chief}", "");return xml;}// 獲取印章寬度: 個(gè)人簽名:高度1.8cm;個(gè)人執(zhí)業(yè)資格:高度3cm,寬度:4.5cm; 公司公章:最大4.2cmprivate static String getpWidth(String pType, Object sealPeronal,double width) {double pWidth = 100;String sealPeronalType = String.valueOf(sealPeronal);// 公章if ("photo_superName".equalsIgnoreCase(pType)|| "photo_super".equalsIgnoreCase(pType)) {pWidth = width > 119 ? 119 : width;// 個(gè)人簽章:執(zhí)業(yè)資格} else if ("photo_engineer".equalsIgnoreCase(pType)&& "1001".equals(sealPeronalType)) {pWidth = width > 126 ? 126 : width;// 個(gè)人簽章:簽名} else if ("photo_engineer".equalsIgnoreCase(pType)) {pWidth = width > 195 ? 195 : width;// 個(gè)人簽章:執(zhí)業(yè)資格} else if ("photo_chief".equalsIgnoreCase(pType)&& "1001".equals(sealPeronalType)) {pWidth = width > 126 ? 126 : width;// 個(gè)人簽章:簽名} else if ("photo_chief".equalsIgnoreCase(pType)) {pWidth = width > 202 ? 202 : width;}return String.valueOf(pWidth);}// 獲取印章寬度: 個(gè)人簽名:高度1.8cm;個(gè)人執(zhí)業(yè)資格:高度3cm,寬度:4.5cm; 公司公章:最大4.2cmprivate static String getpHeight(String pType, Object sealPeronal,double height) {double pHeight = 100;String sealPeronalType = String.valueOf(sealPeronal);// 公章if ("photo_superName".equalsIgnoreCase(pType)|| "photo_super".equalsIgnoreCase(pType)) {pHeight = height > 119 ? 119 : height;// 個(gè)人簽章:執(zhí)業(yè)資格} else if ("photo_engineer".equalsIgnoreCase(pType)&& "1001".equals(sealPeronalType)) {pHeight = height > 84 ? 84 : height;// 個(gè)人簽章:簽名} else if ("photo_chief".equalsIgnoreCase(pType)&& "1001".equals(sealPeronalType)) {pHeight = height > 84 ? 84 : height;} else if ("photo_engineer".equalsIgnoreCase(pType)|| "photo_chief".equalsIgnoreCase(pType)) {pHeight = height > 50.4 ? 50.4 : height;}return String.valueOf(pHeight);}/*** 讀取圖片信息* * @date 2014.10.22* @param path*/protected static ImageDto readImageInfo(String path) {// path = "d:/b3.jpg";if (StringUtils.isEmpty(path)) {throw new NullPointerException("圖片路徑為空!");}File file = new File(path);if (!file.exists()) {throw new NullPointerException("圖片不存在,路徑為:" + path);}ImageDto dto = null;BufferedImage bi = null;ByteArrayOutputStream bos = null;FileInputStream fis = null;try {dto = new ImageDto();fis = new FileInputStream(file);bos = new ByteArrayOutputStream(1000);byte[] bytes = new byte[1024];while ((fis.read(bytes)) != -1) {bos.write(bytes);}bi = ImageIO.read(file);dto.setWidth(bi.getWidth());dto.setHeight(bi.getHeight());dto.setBase64(Base64.encode(bos.toByteArray()));} catch (IOException e) {e.printStackTrace();} finally {if (fis != null) {try {fis.close();} catch (IOException e) {e.printStackTrace();}}if (bos != null) {try {bos.close();} catch (IOException e) {e.printStackTrace();}}}return dto;}// 關(guān)閉IOprotected static void close(BufferedReader br, OutputStream os) {if (br != null) {try {br.close();} catch (IOException e) {e.printStackTrace();}}if (os != null) {try {os.flush();} catch (IOException e) {e.printStackTrace();}try {os.close();} catch (IOException e) {e.printStackTrace();}}}// 關(guān)閉IOprotected static void close(FileInputStream fis, ByteArrayOutputStream bos) {if (fis != null) {try {fis.close();} catch (IOException e) {e.printStackTrace();}}if (bos != null) {try {bos.flush();} catch (IOException e) {e.printStackTrace();}try {bos.close();} catch (IOException e) {e.printStackTrace();}}}/*** 簽名:在文字的右側(cè)*/protected static final String IMG_RIGHT = ""+ " <w:pict> "+ " <v:shapetype id=\"_x0000_t75\" coordsize=\"21600,21600\" o:spt=\"75\" "+ " o:preferrelative=\"t\" path=\"m@4@5l@4@11@9@11@9@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://03000002.png\" xml:space=\"preserve\">${photo_tag}</w:binData> "+ " <v:shape id=\"圖片 1\" o:spid=\"_x0000_i1025\" type=\"#_x0000_t75\" "+ " style=\"margin-top:10pt;width:106.5pt;height:48pt;z-index:1;visibility:visible;mso-wrap-style:square\"> "+ " <v:imagedata src=\"wordml://03000002.png\" o:title=\"\" /> "+ " </v:shape> " + " </w:pict> ";/*** 位置:在圖片的上方* */protected static final String IMG_UP = ""+ " <w:pict> "+ " <v:shapetype id=\"_x0000_t75\" coordsize=\"21600,21600\" o:spt=\"75\" "+ " o:preferrelative=\"t\" path=\"m@4@5l@4@11@9@11@9@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://0300000${pict_index}.png\" xml:space=\"preserve\">${pict_tag}</w:binData> "+ " <v:shape id=\"圖片 3\" o:spid=\"_x0000_s1026\" type=\"#_x0000_t75\" "+ " style=\"position:absolute;left:0;text-align:left;margin-left:${pict_position_left}pt;margin-top:${pict_position_top}pt;width:${pict_width}pt;height:${pict_height}pt;z-index:1;visibility:visible;mso-wrap-style:square;mso-width-percent:0;mso-height-percent:0;mso-wrap-distance-left:9pt;mso-wrap-distance-top:0;mso-wrap-distance-right:9pt;mso-wrap-distance-bottom:0;mso-position-horizontal:absolute;mso-position-horizontal-relative:text;mso-position-vertical:absolute;mso-position-vertical-relative:text;mso-width-percent:0;mso-height-percent:0;mso-width-relative:margin;mso-height-relative:margin\"> "+ " <v:imagedata src=\"wordml://0300000${pict_index}.png\" o:title=\"\" /> "+ " </v:shape> " + " </w:pict> ";} 2. 在具體需要導(dǎo)出的功能的查詢單條記錄的方法中加入代碼
// 導(dǎo)出word if (WordUtils.WORD_EXP_TAG_VALUE.equals(request .getParameter(WordUtils.WORD_EXP_TAG))) { WordUtils.exp(request, response, dto); return null; }
3. 導(dǎo)出頁面
<!-- 導(dǎo)出WORD --> <div><form id="WordForm" name="WordForm" method="post" action="query.do"> <!-- 查詢路徑 --> <input type="hidden" name="<%=WordUtils.WORD_EXP_TAG %>" value="<%=WordUtils.WORD_EXP_TAG_VALUE %>"/><!-- 用于判斷是否為導(dǎo)出功能,無需修改 --> <input type="hidden" name="<%=WordUtils.WORD_TEMPLATE_NAME %>" value="start.xml"/> <!-- 模板名稱:模板放在page/project/template_word下 --> <input type="hidden" name="<%=WordUtils.WORD_FILE_NAME %>" value="開工令"/> <!-- 導(dǎo)出的WORD名稱(注:系統(tǒng)會(huì)自動(dòng)為名稱后加上當(dāng)前日期) --> <input type="hidden" name="id" id="id"/> <input type="hidden" name="handleType" id="handleType" value="<%=IEnginerringStartConstant.HANDLE_BROWSE%>"/> </form></div> 4. 導(dǎo)出js
// 導(dǎo)出 EnginerringStartHandle.exp = function(){ var id = $("#modifyId").val(); if(!id){ $.messager.alert('提示',"請(qǐng)先保存數(shù)據(jù)",'info'); return; } $("#id").val(id); $.messager.progress({ msg:'正在處理,請(qǐng)等待...' }); $("#WordForm").submit(); setTimeout("$.messager.progress('close')",6000); };
總結(jié)
以上是生活随笔為你收集整理的通过xml方式根据word模板导出word的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javascript进阶面向对象ES6
- 下一篇: c语言中short作用,详解C语言中整数