1 . 实现代码

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;/*** 导出WORD* * @author ZHEN.L* @date 2014.09.23* @date 2014.11.05* */
public class WordUtils {/*** 转换PDF格式*/public static final String WORD_2_PDF = "Word.pdf";/*** word导出标记*/public static final String WORD_EXP_TAG = "Word.exp";/*** word导出值*/public static final String WORD_EXP_TAG_VALUE = "word";/*** 模板名称标记*/public static final String WORD_TEMPLATE_NAME = "Word.fileName";/*** 模板名称标记*/public static final String WORD_FILE_NAME = "fileName";/*** 模板名称标记:动态字段*/public static final String WORD_FILE_NAME_FIELD = "FieldfileName";// 模板路径protected static final String WORD_TEMPLATE_PATH = "\\page\\project\\template_word\\";/*** word中换行:需要将word中\r\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") + "/";/*** 导出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;}// 将文件,转换成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; // 图片序号标记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);// 设计思想: 首先将XML中图片标记${key}替换为word图片对应的XML;// 第二,将${photo_tag}图片(电子印章)替换为对应的${key}值,再将${key}替换为base64,// 公司公章:大部分长度4.2cm,个别长度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}", // 替换图片序列号String.valueOf(photoIndex));photoXml = photoXml.replace("${pict_position_left}",pict_position_left); // 替换图片左侧位置photoXml = photoXml.replace("${pict_position_top}",pict_position_top); // 替换图片上部位置// 像素和厘米之间的换算是需要知道图片的分辨率的。通常设计网页的时候,图片的分辨率一般都是用72dpi的,// 即72像素/英寸,由于1英寸= 2.54厘米,所以在设计网页的时候,一般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);// 个人签章:个人签名(高1.8cm,宽待定)、执业资格章(高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); // 替换图片左侧位置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;}// 获取印章宽度: 个人签名:高度1.8cm;个人执业资格:高度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;// 个人签章:执业资格} else if ("photo_engineer".equalsIgnoreCase(pType)&& "1001".equals(sealPeronalType)) {pWidth = width > 126 ? 126 : width;// 个人签章:签名} else if ("photo_engineer".equalsIgnoreCase(pType)) {pWidth = width > 195 ? 195 : width;// 个人签章:执业资格} else if ("photo_chief".equalsIgnoreCase(pType)&& "1001".equals(sealPeronalType)) {pWidth = width > 126 ? 126 : width;// 个人签章:签名} else if ("photo_chief".equalsIgnoreCase(pType)) {pWidth = width > 202 ? 202 : width;}return String.valueOf(pWidth);}// 获取印章宽度: 个人签名:高度1.8cm;个人执业资格:高度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;// 个人签章:执业资格} else if ("photo_engineer".equalsIgnoreCase(pType)&& "1001".equals(sealPeronalType)) {pHeight = height > 84 ? 84 : height;// 个人签章:签名} 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;}// 关闭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();}}}// 关闭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();}}}/*** 签名:在文字的右侧*/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. 在具体需要导出的功能的查询单条记录的方法中加入代码

// 导出word  if (WordUtils.WORD_EXP_TAG_VALUE.equals(request  .getParameter(WordUtils.WORD_EXP_TAG))) {  WordUtils.exp(request, response, dto);  return null;  } 

3. 导出页面

<!-- 导出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 %>"/><!-- 用于判断是否为导出功能,无需修改 -->  <input type="hidden" name="<%=WordUtils.WORD_TEMPLATE_NAME %>" value="start.xml"/> <!-- 模板名称:模板放在page/project/template_word下 -->  <input type="hidden" name="<%=WordUtils.WORD_FILE_NAME %>" value="开工令"/> <!-- 导出的WORD名称(注:系统会自动为名称后加上当前日期) -->  <input type="hidden" name="id" id="id"/>  <input type="hidden" name="handleType" id="handleType" value="<%=IEnginerringStartConstant.HANDLE_BROWSE%>"/>
</form></div>

4. 导出js

// 导出
EnginerringStartHandle.exp = function(){  var id = $("#modifyId").val();  if(!id){  $.messager.alert('提示',"请先保存数据",'info');  return;  }  $("#id").val(id);  $.messager.progress({  msg:'正在处理,请等待...'  });  $("#WordForm").submit();  setTimeout("$.messager.progress('close')",6000);
};  

通过xml方式根据word模板导出word相关推荐

  1. poi-tl,根据word模板导出word(表格行循环,表格无表头的情况)

    最近项目里要做一个根据客户提供的word模板导出word的功能,方法有很多,比如easyPoi(对word的支持并不是很好),freeMark(太麻烦不想研究),以及poi-tl, 最后研究了半天发现 ...

  2. Springboot--使用POI,根据word模板导出word文件

    需求:根据一个word模板,在程序中替换模板中的参数,然后根据这个模板导出word文件. 引入POI对word操作的依赖: <dependency><groupId>org.a ...

  3. java 导出word,java根据提供word模板导出word文档

    本文主要讲解,利用poi-tl在word中动态生成表格行,进行文字.图片填充.一共提供了两种方式,1.基于本地文件 2.基于网络文件 本文讲解思路,1.先看示例,2. 示例对应的代码展示 3. 基本概 ...

  4. python连接小程序云开发数据库,并根据word模板导出word

    需求:微信小程序云开发数据库存储,需要将数据库中的答案进行导出,从而生成一个word 难点1: 利用python的docxtpl包进行模板导出 难点2: python获取云开发的数据库数据 难点3: ...

  5. 用word模板导出word文档

    项目需求要把页面上的分析结果导出为word文档,实现的办法是POI.查了一下网上很多方式都采用FreeMark,自己认为比较麻烦,所以还是采取了POI导出.之前的框架是SSH的,现在换成了Spring ...

  6. 基于Easypoi+jfree,使用SpringBoot架构,Java编程实现word模板导出Word报表

    目录 1.项目目录结构 2.pom.xml添加的依赖 3.编写jfreeutil工具类 4.编写wordutil工具类 5.编写word模板 7.运行效果 8.复杂布局实现 8.1如何实现图片并排 S ...

  7. java根据提供word模板导出word文档

    涉及主要jar包为 freemarker-2.3.10.jar,servlet-api-2.4.jar. (1)首先修改 word模板如下形式,把需要查询写入word的值用${}形式封装 (2)把 w ...

  8. Aspose.Words利用Word模板导出Word文档

    今天工作中遇到了导出Word文档的问题,但是在搜索Aspose.Words 导出Word文档时发现网上的方法都是有头没尾的,有的只有一小段实例,让人看着摸不着头脑. 利用Aspose.Words导出W ...

  9. 使用Word模板导出Word后,表格后面产生空白页

    目录 背景 解决 参考 背景 项目中有导出Word功能,其实现逻辑是先整理一个Word文档,里面使用占位符:代码读取Word文档,然后替换占位符. 但出现这样的问题:填充某个表格后,表格后面出现了空白 ...

  10. Java使用word模板导出word

    1.创建一个空的springboot工程,引入jar包 <dependency><groupId>org.apache.poi</groupId><artif ...

最新文章

  1. OpenBLAS简介及在Windows7 VS2013上源码的编译过程
  2. 通过angular.js实现MVC的基本步骤
  3. 在Mac下的前端开发必备工具
  4. linux java程序控制台日志输出
  5. AppDelegate瘦身之服务化
  6. IE8给你选择的理由
  7. Python 内置模块之 asyncio(异步iO)
  8. 8051 管脚定义_8051微控制器的引脚说明
  9. mac使用codelite运行程序没有输出
  10. 数字图像处理(作业三)——孔洞填充+全局阈值+自适应阈值
  11. 系统登录界面(收集)
  12. python中列表,元组,字典常用操作方法的总结
  13. paip.导入数据英文音标到数据库mysql为空的问题之道解决原理
  14. 服务器2012导出日志文件,MDT2012,client部署日志存放在服务器上
  15. 利用Python进行游戏脚本编程,不愧是最强的脚本语言!
  16. 数字调制中比特率和波特率的关系
  17. 微软drive服务器,OneDrive:微软云存储服务
  18. 阿里云默认80端口无法访问
  19. 微信公众号自动回复海报
  20. 洛谷 P3324 [SDOI2015]星际战争 二分答案+网络流

热门文章

  1. linux 运行.deb,Ubuntu下如何用命令行运行deb安装包
  2. Linux 下 Android NDK 编译 openssl
  3. 还在为日语动词变形感到困惑吗?一张图即可搞定
  4. java 栅栏_Java并发基础-栅栏(CountDownLatch)与闭锁(CyclicBarrier)
  5. PCU-285锡膏粘度计优点及特点
  6. 腾讯裁员范围扩大;研究称人类或能喝到月球冰火水;苹果考虑取消京东方3000万块屏幕订单;近视手术无法治愈近视
  7. 李开复创办创新工场的发言稿及访谈
  8. android 读取 json 字符串文件遇到的一个坑 W/art: Suspending all threads took: xx.xxx ms
  9. SCLK时钟信号可以高电平有效也可以低电平有效
  10. H3C网络流量镜像配置