精华内容
参与话题
问答
  • POI模板导出word

    千次阅读 2016-04-17 22:18:27
    java使用poi模板方式完成word导出,亲测可用。

    前言: 要做一个wod导出,java有很多实现方式,比如iText,POI,FreeMarker,Jacob等等,由于之前公司使用的一直是提供的封装好的报告服务,直接调用,就从来没有仔细想过没有了公司的报告服务怎么做,最要命的是总是认为一个干了多年的程序员还好意思问word导出怎么写,会招来很多的鄙视,事实是那些觉着不屑一提的大神口若悬河的跟你说某些技术的时候,他们真的连word导出也写不出来,他们的大放厥词的技术只适合用来面试,不行你可以试试。


    总结: 对于使用word模板导出,通过对几种方式的总结,发现POI是勉强不错的方式,但是网上千篇一律的 创建一个模板然后保存成xml,然后修改内容,(或者再保存为ftl格式文件)。我就想强强的问一句用模板的意义是什么呢?

    使用模板的本意就是要让客户可以直接修改模板的内容、文字样式等,如果还要修改xml内容,各种文件格式保存,这么傻逼的模板方式还有意义吗?,或者提供了doc的模板后,导出后word打不开,真是服!


    方案:下面提供本人亲测 两种POI方式的 word导出。


    环境:准备jar包,本案例使用的是poi3.7 版本


    1,使用模板方式:模板见附件。

      1),新建一个word文档,命名detail.docx,定义几个 变量 如图: 注意几个变量最好 先在记事本上写好,然后粘过来,因为word底层编译成xml的时候很不友好,容易将你写的东西分割,无语。




    2),敲代码吧。

    1,使用模板的方式。

    package com.trs.om.screenshow.hotnewsshow.struts2;
    
    import java.io.FileOutputStream;
    import java.io.OutputStream;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import org.apache.commons.lang.StringUtils;
    import org.apache.poi.POIXMLDocument;
    import org.apache.poi.openxml4j.opc.OPCPackage;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    import org.apache.poi.xwpf.usermodel.XWPFRun;
    
    import com.trs.om.util.HTMLUtil;
    
    /**
     * poi模板方式导出word
     * @author zhaozuofa
     * 2016年4月15日 下午3:43:40
     *
     */
    public class ExportWordPOI {
        public static void searchAndReplace(String srcPath, String title,Map<String, String> map) {
                    try {
                        OPCPackage pack = POIXMLDocument.openPackage(srcPath);
                        XWPFDocument doc = new XWPFDocument(pack);
                        List<XWPFParagraph> paragraphs = doc.getParagraphs();
                        String content = "";
                        for (XWPFParagraph tmp : paragraphs) {
                            List<XWPFRun> runs = tmp.getRuns();
                            for (XWPFRun r : runs) {
                                for (Entry<String, String> e : map.entrySet()) {
                                    if (r.getText(0).trim().equals(e.getKey())) {
                                      //处理字段内容中的 换行,网上各种bb,就是不解决问题什么  (char)11啊,\r啊 自己试验的实验的时候都扯淡
                                        //解决原理是:根据内容中要换行的依据进行分割成数组或集合,在通过 poi提供的换行方法分别写入。
                                        if(r.getText(0).trim().equals("${content}")){
                                            content =map.get(r.getText(0).trim());
                                            r.setText("",0);
                                                    String strsf[] = content.split("\r\n");
                                                    for(int i = 0;i<strsf.length;i++){
                                                        if(StringUtils.isNotEmpty(strsf[i])){
                                                                String textContent = strsf[i].replaceAll("  ", "");
                                                                r.setText("\n"+textContent);
                                                                r.addCarriageReturn();
                                                        }
                                                    }
                                        }else{
                                            r.setText("\n"+map.get(r.getText(0).trim()),0);
                                        }
                                    }
                                }
                            }
                        }
    
                        String wname = HTMLUtil.replaceBlank(title)+".docx";
                        wname = new String(wname.getBytes("gb2312"), "iso8859-1");//格式化文件中文名称,解决乱码
    
                        //1, web项目时,浏览器点击导出时,弹出下载框
                       /* HttpServletResponse response = ServletActionContext.getResponse();
                        response.setContentType("application/msword; charset=utf-8");
                        response.setHeader("Content-Disposition","attachment;filename="+wname);
                        response.setCharacterEncoding("utf-8");
                        OutputStream outfa = response.getOutputStream();*/
    
                        //2,java项目直接保存在指定硬盘中,路径可以通过参数传递,本例直接写死,懂得道理就可以。
                        OutputStream outfa = new FileOutputStream("D:\\word\\newLine2.doc");
    
                        doc.write(outfa);
                        outfa.flush();
                        outfa.close();
    
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
    
        }
    
        public static void main(String[] args) {
            ExportWordPOI pt = new ExportWordPOI();
            //模板文件路径
            String str =  "d:\\word\\detail.docx";
           // String str =  ServletActionContext.getServletContext().getRealPath("/WEB-INF/detail/detail.docx");//这样可以获取项目下的枯井
            HashMap<String,String> map = new HashMap<String,String>();
            map.put("${topdata}", "2016-04-17,环球网");
            map.put("${title}",  "我是测试标题");
            map.put("${content}", "我是一条测试的内容数据");
    
            pt.searchAndReplace(str, "测试", map);
    
    
        }
    }
    



    2,快速导出,不使用模板的方式,可参看:http://blog.csdn.net/w8700569/article/details/7288149


    package com.trs.om.screenshow.hotnewsshow.struts2;
    
    import java.io.FileOutputStream;
    
    import org.apache.poi.xwpf.usermodel.Borders;
    import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
    import org.apache.poi.xwpf.usermodel.TextAlignment;
    import org.apache.poi.xwpf.usermodel.UnderlinePatterns;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    import org.apache.poi.xwpf.usermodel.XWPFRun;
    
    public class Test {
        public static void main(String[] args) throws Exception {
            XWPFDocument doc = new XWPFDocument();
    
            XWPFParagraph p1 = doc.createParagraph();
            p1.setAlignment(ParagraphAlignment.CENTER);//文字对齐方式
            /*p1.setBorderBottom(Borders.DOUBLE);
            p1.setBorderTop(Borders.DOUBLE);
    
            p1.setBorderRight(Borders.DOUBLE);
            p1.setBorderLeft(Borders.DOUBLE);
            p1.setBorderBetween(Borders.SINGLE);*/
    
            p1.setVerticalAlignment(TextAlignment.TOP);
    
            XWPFRun r1 = p1.createRun();
            r1.setText("我是第一条测试数据");
            r1.setBold(true);//是否加粗
            r1.setFontFamily("宋体");//字体类型
            r1.setFontSize(16);//字体大小
            r1.setUnderline(UnderlinePatterns.DOT_DOT_DASH);//字体是否有下划线
            r1.addBreak();//换行
            r1.setTextPosition(400);//上下两行文字之间间隔
    
            XWPFParagraph p2 = doc.createParagraph();
            p2.setAlignment(ParagraphAlignment.RIGHT);
    
            //BORDERS
            p2.setBorderBottom(Borders.DOUBLE);
            p2.setBorderTop(Borders.DOUBLE);
            p2.setBorderRight(Borders.DOUBLE);
            p2.setBorderLeft(Borders.DOUBLE);
            p2.setBorderBetween(Borders.SINGLE);
    
            XWPFRun r2 = p2.createRun();
            r2.setText("我是第二条测试数据");
            r2.setStrike(true);
            r2.setFontSize(20);
    
    
            FileOutputStream out = new FileOutputStream("d:\\word\\test.docx");
            doc.write(out);
            out.close();
    
        }
    }
    
    











    展开全文
  • doc文件的读取,需要导入poi-scratchpad包: docx文件读取,需要导入poi-ooxml包: 一、引入pom <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</...

    注意: 

    • doc文件的读取,需要导入poi-scratchpad包:
    • docx文件读取,需要导入poi-ooxml包:

    一、引入pom

    	    <dependency>
    		    <groupId>org.apache.poi</groupId>
    			<artifactId>poi</artifactId>
    			<version>3.10.1</version>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi-scratchpad</artifactId>
    			<version>3.10.1</version>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi-ooxml</artifactId>
    			<version>3.10.1</version>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi-ooxml-schemas</artifactId>
    			<version>3.10.1</version>
    		</dependency>

     二、新建一个docx文件作为模板,里面需要替换的部分用{xxx}标识出来

    三、接口内容如下:

        /**
         * 生成简历
         *
         * @param model
         * @return
         * @throws Exception
         */
        @RequestMapping(value = {"/down"}, method = {RequestMethod.GET, RequestMethod.POST})
        public void down(HttpServletResponse response, @CookieValue(SessionManager.SESSION_NAME) String sessionId) throws Exception {
            SysUser user = userSessionManager.getUser(sessionId);
            AdjustAbilityPerson bean = this.adjustAbilityPersonRepository.findByuser(user.getId());
            String path = templateDir;
            XWPFDocument xwpfDocument = this.downLoadFile(response, bean, path, user);//创建对象
            response.reset();
            response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("个人简历.docx", "UTF-8"));
            response.setContentType("application/octet-stream");
            OutputStream out = response.getOutputStream();
            xwpfDocument.write(out);//将word对象内容写入输出流
        }

    三、上图中downLoadFile方法内容

        public XWPFDocument downLoadFile(HttpServletResponse response, AdjustAbilityPerson bean, String filePath, SysUser user) throws Exception {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Map<String, String> map = new HashMap<String, String>();//把要替换的内容放入map
            filePath = filePath + "/" + "jianli.docx";//模板文件名称
            if (bean != null) {
                String str = "";
                map.put("{userName}", bean.getUserName() != null ? bean.getUserName() + "" : "");
                if (bean.getSex() != null && bean.getSex() == 0) {
                    map.put("{sexName}", "男");
                } else if (bean.getSex() != null && bean.getSex() == 1) {
                    map.put("{sexName}", "女");
                } else {
                    map.put("{sexName}", "");
                }
                //省略其他的替换……
            }
            OPCPackage pack = POIXMLDocument.openPackage(filePath);//打开word模板文件
            XWPFDocument document = new XWPFDocument(pack);//创建word对象
            CommonFileUtil.replaceStrs(document, map);//替换内容
            imagerList(document, pack,bean.getCreateuser().getId());//简历有图片,插入图片
            return document;
        }

     四、上图插入图片方法imagerList

        private void imagerList(XWPFDocument document, OPCPackage pack, Long id) throws IOException {
            ImagerXWPFDocument doc = new ImagerXWPFDocument(pack);
            List<XWPFTable> ts = document.getTables();
            XWPFTable table = ts.get(0);
            int rowinx = 0;
            XWPFTableRow row = null;
            List<Affix> affixs1 = this.affixService.findAffixsByObjectId(5002, id + "");
            if (affixs1 != null && affixs1.size() > 0) {
                row = table.getRow(0);
                Map<String, Object> imager = new HashMap<String, Object>();
                imager.put("width", 115);
                imager.put("height", 180);
                String filePath = this.affixConfig.getBaseDir() + affixs1.get(0).getSource();
                if(!new File(filePath).exists()){
                    return;
                }
                InputStream in = new FileInputStream(filePath);
                byte[] content = CommonFileUtil.inputStream2ByteArray(in, false);
                imager.put("content", content);
                imager.put("type", "");
                XWPFParagraph paragraph = null;
                XWPFTableCell cell = row.getCell(4);
                List<XWPFParagraph> paragraphs = cell.getParagraphs();
                paragraph = paragraphs.get(0);
                CommonFileUtil.replaceImgager(paragraph, imager, doc);
            }
        }

    五、CommonFileUtil工具类包括替换内容,插入图片、文件复制等功能

    package cn.com.maxtech.huatai.util;
    
    import java.io.ByteArrayInputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.math.BigInteger;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    import org.apache.log4j.Logger;
    import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
    import org.apache.poi.xwpf.usermodel.TextAlignment;
    import org.apache.poi.xwpf.usermodel.UnderlinePatterns;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    import org.apache.poi.xwpf.usermodel.XWPFRun;
    import org.apache.poi.xwpf.usermodel.XWPFTable;
    import org.apache.poi.xwpf.usermodel.XWPFTableCell;
    import org.apache.poi.xwpf.usermodel.XWPFTableRow;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;
    /** 
     * 公共文件类
     * */
    public class CommonFileUtil {
    	protected final static Logger log = Logger.getLogger(CommonFileUtil.class);
    	/**
    	 * 替换文档中的内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * */
    	public static void replaceStrs(XWPFDocument document,Map<String,String> map){
    		replaceStrs(document, map,null);
    	}
    	/**
    	 * 替换文档中的内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * @param list 显示下划线的key集合
    	 * */
    	public static void replaceStrs(XWPFDocument document,Map<String,String> map,List<String> list){
    		replaceParagraphStrs(document, map,list);
    		replaceTableStrs(document, map,list);
    	}
    	/**
    	 * 替换文档中的内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * @param list 显示下划线的key集合
    	 * @param removes 删除指定key所在的表格行的key集合
    	 * */
    	public static void replaceStrs(XWPFDocument document,Map<String,String> map,List<String> list,
    			List<String> removes){
    		replaceParagraphStrs(document, map,list);
    		replaceTableStrs(document, map,list,null,null,removes);
    	}
    	/**
    	 * 替换文档中的内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * @param list 显示下划线的key集合
    	 * @param breaks 多行显示的key集合
    	 * @param separator 分隔符
    	 * @param removes 删除指定key所在的表格行的key集合
    	 * */
    	public static void replaceStrs(XWPFDocument document,Map<String,String> map,List<String> list,
    			List<String> breaks,String separator,List<String> removes){
    		replaceParagraphStrs(document, map,list,breaks,separator);
    		replaceTableStrs(document, map,list,breaks,separator,removes);
    	}
    	/**
    	 * 替换段落中的内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * */
    	public static void replaceParagraphStrs(XWPFDocument document,Map<String,String> map){
    		replaceParagraphStrs(document, map, null);
    	}
    	/**
    	 * 替换段落中的内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * @param list 显示下划线的key集合
    	 * */
    	public static void replaceParagraphStrs(XWPFDocument document,Map<String,String> map,List<String> list){
    		replaceParagraphStrs(document, map, list,null,null);
    	}
    	
    	/**
    	 * 替换段落中的内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * @param breaks 多行显示的key集合
    	 * @param separator 分隔符
    	 * */
    	public static void replaceParagraphStrs(XWPFDocument document,Map<String,String> map,List<String> breaks,String separator){
    		replaceParagraphStrs(document, map, null, breaks, separator,null);
    	}
    	
    	/**
    	 * 替换段落中的内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * @param list 显示下划线的key集合
    	 * @param breaks 多行显示的key集合
    	 * @param separator 分隔符
    	 * */
    	public static void replaceParagraphStrs(XWPFDocument document,Map<String,String> map,List<String> list,
    			List<String> breaks,String separator){
    		replaceParagraphStrs(document, map, list, breaks, separator,null);
    	}
    	
    	/**
    	 * 替换段落中的内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * @param list 显示下划线的key集合
    	 * @param breaks 多行显示的key集合
    	 * @param separator 分隔符
    	 * @param replaceList 使用指定存在函数替换为key集合
    	 * */
    	public static void replaceParagraphStrs(XWPFDocument document,Map<String,String> map,List<String> list,
    			List<String> breaks,String separator,List<String> replaceList){
    		replaceParagraphStrs(document, map, list, breaks, separator, replaceList,null,null,null,null,null);
    	}
    	/**
    	 * 替换段落中的内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * @param list 显示下划线的key集合
    	 * @param breaks 多行显示的key集合
    	 * @param separator 分隔符
    	 * @param replaceList 使用指定存在函数替换为key集合
    	 * @param removeList 要删除标题的内容key集合
    	 * */
    	public static void replaceParagraphStrs(XWPFDocument document,Map<String,String> map,List<String> list,
    			List<String> breaks,String separator,List<String> replaceList,List<String> removeList){
    		replaceParagraphStrs(document, map, list, breaks, separator, replaceList,null,null,null,null,removeList);
    	}
    	
    	/**
    	 * 替换段落中的内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * @param list 显示下划线的key集合
    	 * @param breaks 多行显示的key集合
    	 * @param separator 分隔符
    	 * @param replaceList 使用指定存在函数替换为key集合
    	 * @param fontFamily 字体
    	 * @param fontSize 文字大小
    	 * @param fontBold 是否加粗
    	 * @param showLine 是否显示下划线
    	 * @param removeList 要删除标题的内容key集合
    	 * */
    	public static void replaceParagraphStrs(XWPFDocument document,Map<String,String> map,List<String> list,
    			List<String> breaks,String separator,List<String> replaceList,String fontFamily,Integer fontSize,
    				Boolean fontBold,Boolean showLine,List<String> removeList){
    		boolean removeTag=false;
    		if(removeList!=null&&removeList.size()>0){
    			removeTag=true;
    		}
    		boolean replaceTag=false;
    		if(replaceList!=null&&replaceList.size()>0){
    			replaceTag=true;
    		}
    		boolean flag=false;
    		if(list!=null&&list.size()>0){
    			flag=true;
    		}
    		boolean flags=false;
    		if(breaks!=null&&breaks.size()>0&&separator!=null&&!"".equals(separator)){
    			flags=true;
    		}
    		Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();
    		String mkey=null;
    		String temp=null;
    		Iterator<String> iterator = null;
    		XWPFRun xwpfRun=null;
    		while (itPara.hasNext()) {
    			boolean tag=false;
                  XWPFParagraph paragraph = (XWPFParagraph) itPara.next();
                  iterator = map.keySet().iterator();
                  while (iterator.hasNext()) {
                	  mkey = iterator.next();
                      List<XWPFRun> run=paragraph.getRuns();
                      for(int i=0;i<run.size();i++){
                    	  xwpfRun=run.get(i);
                    	  temp=xwpfRun.getText(xwpfRun.getTextPosition());
                          if(temp!=null ){
                        	  boolean tgs=false;
                        	  if(replaceTag&&replaceList.contains(mkey)){
                				  tgs=temp.trim().contains(mkey);
                			  }else{
                				  tgs=temp.trim().equals(mkey);
                			  }
                        	  if(tgs&&removeTag&&removeList.contains(mkey)){
                        		  xwpfRun.removeBreak();
                        		  continue;
                        	  }
                        	  if(tgs){
                        		  if(flag&&list.contains(mkey)){//设置下划线属性
                        			  xwpfRun.setUnderline(UnderlinePatterns.DOT_DOT_DASH);
                        		  }
                        		  if(flags&&breaks.contains(mkey)){
                        			  xwpfRun.setText("",0);  
                        			  tag=true;
                        			  break;
                        		  }else{
                        			  if(replaceTag&&replaceList.contains(mkey)){
                        				  xwpfRun.setText(replaceStrs(temp,map,replaceList),0); 
                        			  }else{
                        				  xwpfRun.setText(map.get(mkey)==null?"":map.get(mkey),0);    
                        			  }
                        			  if(fontFamily!=null&&!fontFamily.equals("")){
                        				  xwpfRun.setFontFamily("宋体");  
                             		  }
                             		  if(fontSize!=null){
                             			 xwpfRun.setFontSize(fontSize);
                             		  }
                             		  if(fontBold!=null&&fontBold){
                              			 xwpfRun.setBold(true);  
                              		  }
                             		  if(showLine!=null&&showLine){
                             			 xwpfRun.setUnderline(UnderlinePatterns.DOT_DOT_DASH);
                             		  }
                        		  }
                        	  }
                          }
                      }    
                      if(tag){
                    	  tag=false;
                    	  if(map.get(mkey)!=null){
                    		  String[] sts=map.get(mkey).split(separator);
                    		  if(sts.length>0){
                    			  for (int j =0; j <= sts.length-1; j++) {
                    				  XWPFRun run_s = paragraph.insertNewRun(paragraph.getRuns().size()-1); 
                    				  run_s.setText(sts[j]); 
                    				  if(j<sts.length-1){
                    					  run_s.addBreak();
                    				  }
                    				  if(fontFamily!=null&&!fontFamily.equals("")){
                    					  run_s.setFontFamily("宋体");  
                    				  }
                    				  if(fontSize!=null){
                    					  run_s.setFontSize(fontSize);
                    				  }
                    				  if(fontBold!=null&&fontBold){
                    					  xwpfRun.setBold(true);  
                    				  }
                    				  if(showLine!=null&&showLine){
                    					  xwpfRun.setUnderline(UnderlinePatterns.DOT_DOT_DASH);
                    				  }
                    			  }
                    		  }
                    	  }
                      }
                  } 
    		}
    	}
    	
    	private static String replaceStrs(String strs,Map<String,String> map,List<String> replaceList){
    		String value="";
    		String key="";
    		for (int i = 0; i < replaceList.size(); i++) {
    			key=replaceList.get(i);
    			value=map.get(key);
    			if(value!=null){
    				strs=strs.replace(key, value);
    			}
    		}
    		return strs;
    	}
    
    	/**
    	 * 替换表格中内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * */
    	public static void replaceTableStrs(XWPFDocument document,Map<String,String> map){
    		replaceTableStrs(document, map, null);
    	}
    	/**
    	 * 替换表格中内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * @param list 显示下划线的key集合
    	 * */
    	public static void replaceTableStrs(XWPFDocument document,Map<String,String> map,List<String> list){
    		replaceTableStrs(document, map, list, null, null);
    	}
    	/**
    	 * 替换表格中内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * @param list 显示下划线的key集合
    	 * @param breaks 多行显示的key集合
    	 * @param separator 分隔符
    	 * */
    	public static void replaceTableStrs(XWPFDocument document,Map<String,String> map,List<String> list,
    			List<String> breaks,String separator){
    		replaceTableStrs(document, map, list, breaks, separator,null);
    	}
    	/**
    	 * 替换表格中内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * @param list 显示下划线的key集合
    	 * @param breaks 多行显示的key集合
    	 * @param separator 分隔符
    	 * @param removes 删除指定key所在的表格行的key集合
    	 * */
    	public static void replaceTableStrs(XWPFDocument document,Map<String,String> map,List<String> list,
    			List<String> breaks,String separator,List<String> removes){
    		replaceTableStrs(document, map, list, breaks, separator, removes,null,null);
    	}
    	/**
    	 * 替换表格中内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * @param list 显示下划线的key集合
    	 * @param breaks 多行显示的key集合
    	 * @param separator 分隔符
    	 * @param removes 删除指定key所在的表格行的key集合
    	 * @param tableIndex 指定的表格索引
    	 * @param isHidden 是否隐藏表格边框
    	 * */
    	public static void replaceTableStrs(XWPFDocument document,Map<String,String> map,List<String> list,
    			List<String> breaks,String separator,List<String> removes,Integer tableIndex,Boolean isHidden){
    		replaceTableStrs(document, map, list, breaks, separator, removes, tableIndex, isHidden,null);
    	}
    	
    	/**
    	 * 替换表格中内容
    	 * @param document 文档对象
    	 * @param map 数据集合
    	 * @param list 显示下划线的key集合
    	 * @param breaks 多行显示的key集合
    	 * @param separator 分隔符
    	 * @param removes 删除指定key所在的表格行的key集合
    	 * @param tableIndex 指定的表格索引
    	 * @param isHidden 是否隐藏表格边框
    	 * @param boldList 要加粗的内容集合
    	 * */
    	public static void replaceTableStrs(XWPFDocument document,Map<String,String> map,List<String> list,
    			List<String> breaks,String separator,List<String> removes,Integer tableIndex,Boolean isHidden,List<String> boldList){
    		if(isHidden==null){
    			isHidden=false;
    		}
    		boolean flag=false;
    		if(list!=null&&list.size()>0){
    			flag=true;
    		}
    		boolean flags=false;
    		if(breaks!=null&&breaks.size()>0&&separator!=null&&!"".equals(separator)){
    			flags=true;
    		}
    		removeTableRow(document, removes);
    		if(tableIndex!=null){
    			XWPFTable table=document.getTables().get(tableIndex);
    			tableControl(table, map, list, breaks, separator, removes, tableIndex, isHidden, flag, flags,boldList);
    		}else{
    			Iterator<XWPFTable> itTable = document.getTablesIterator();
    			while (itTable.hasNext()) {
    				XWPFTable table = (XWPFTable) itTable.next();
    				tableControl(table, map, list, breaks, separator, removes, tableIndex, isHidden, flag, flags,boldList);
    			}
    		}
    		
    	} 
    	
    	private static String getBoldStr(String strs,List<String> boldList){
    		int count=boldList.size();
    		for (int i = 0; i < count; i++) {
    			if(strs.contains(boldList.get(i))){
    				return boldList.get(i);
    			}
    		}
    		return "";
    	}
    	
    	private static void tableControl( XWPFTable table,Map<String,String> map,List<String> list,
    			List<String> breaks,String separator,List<String> removes,Integer tableIndex,Boolean isHidden,
    			boolean flag,boolean flags,List<String> boldList){
    		boolean tagBold=false;
    		if(boldList!=null&&boldList.size()>0){
    			tagBold=true;
    		}
    		if(isHidden){
    			controlTableBorder(table);
    		}
    		String mkey=null;
    		String mvalue=null;
    		String temp=null;
    		XWPFRun xwpfRun=null;
    		Iterator<String> iterator = null;
    		int rcount = table.getNumberOfRows();
            for (int i = 0; i < rcount; i++) {
                XWPFTableRow row = table.getRow(i);
                List<XWPFTableCell> cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                	temp=cell.getText();
                	iterator = map.keySet().iterator();
                	while (iterator.hasNext()) {
                   	    mkey = iterator.next();
                   	    mvalue=map.get(mkey);
                   	    if(mvalue==null){
                   	    	continue;
                   	    }
                    	String s=temp.replace(mkey, mvalue).replace(mkey, mvalue);
                    	List<XWPFParagraph> paras=cell.getParagraphs();
                    	if(paras.size()>0){
                    		for (XWPFParagraph para : paras) { 
                    			boolean tag=false;
    //                			para.setAlignment(ParagraphAlignment.CENTER);
    //                			para.setBorderBottom(Borders.DOUBLE);
    //                			para.setBorderTop(Borders.DOUBLE);
    //                			para.setBorderRight(Borders.DOUBLE);
    //                			para.setBorderLeft(Borders.DOUBLE);
    //                			para.setBorderBetween(Borders.SINGLE);
    //                			para.setVerticalAlignment(TextAlignment.TOP);
                                List<XWPFRun> runs = para.getRuns();  
                       	         for (int k=0; k<runs.size(); k++) { 
                       	        	 xwpfRun=runs.get(k);
                                	 String ts=xwpfRun.getText(xwpfRun.getTextPosition());
                                      if(ts!=null && ts.trim().equals(mkey)){
                                		  if(flag&&list.contains(mkey)){//设置下划线属性
    //                            			  xwpfRun.setUnderline(UnderlinePatterns.DOT_DOT_DASH);
                                			  xwpfRun.setUnderline(UnderlinePatterns.SINGLE);
                                		  }
                                		  if(flags&&breaks.contains(mkey)){
                                			  xwpfRun.setText("",0);  
                                			  tag=true;
                                			  break;
                                		  }else{
                                			  String tempValue=map.get(mkey);
                                			  if(tagBold){
                                				  String boldStr=getBoldStr(tempValue, boldList);
                                				  if(!boldStr.equals("")){
                                					  int a_1=tempValue.indexOf(boldStr);
                                					  String temps=tempValue.substring(a_1+boldStr.length());
                                					  xwpfRun.setBold(true); 
                                					  xwpfRun.setFontFamily("Times New Roman");
                                					  xwpfRun.setFontSize(10);
                                					  xwpfRun.setText(boldStr, 0);
                                					  XWPFRun xwpf=para.createRun();
                                					  xwpf.setText(temps, 0);
                                				  }else{
                                					  xwpfRun.setText(tempValue,0);    
                                				  }
                                			  }else{
                                				  xwpfRun.setText(tempValue,0);
                                			  }
                                		  }
                                      }
                       	         }
                       	         if(tag){
                       	        	tag=false;
                    	        	 String[] sts=map.get(mkey).split(separator);
                    	        	 for (int j =0; j <= sts.length-1; j++) {
                    	        		 XWPFRun run = para.insertNewRun(para.getRuns().size()-1); 
    //                	        		 run.setText(sts[j]); 
                    	        		 String tempValue=sts[j];
    	                       			  if(tagBold){
    	                       				  String boldStr=getBoldStr(tempValue, boldList);
    	                       				  if(!boldStr.equals("")){
    	                       					  int a_1=tempValue.indexOf(boldStr);
    	                       					  String temps=tempValue.substring(a_1+boldStr.length());
    	                       					  run.setBold(true); 
    	                       					  xwpfRun.setFontFamily("Times New Roman");
                            					  xwpfRun.setFontSize(10);
                            					  xwpfRun.setText(boldStr, 0);
    	                       					 run.setText(boldStr);
    	                       					run=para.insertNewRun(para.getRuns().size()-1); 
    	                       					run.setText(temps);
    	                       				  }else{
    	                       					run.setText(tempValue);    
    	                       				  }
    	                       			  }else{
    	                       				run.setText(tempValue);
    	                       			  }
                    	        		 
                    	        		 if(j<sts.length-1){
                    	        			 run.addBreak();
                    	        		 }
                    	        		 
    //                     		 		 run.setFontFamily("宋体");  
    //                     		 		 run.setBold(true);  
                    	        	 }
                    	         }
                            }  
                    	}else{
                    		cell.setText(s);
                    	}
                    }
                }
            }
    	}
    	
    	public static void addParagraphOfTable(XWPFDocument document,Integer tableIndex,Integer rowIndex,Integer cellIndex,List<String> list,
    			String fontFamily,Integer fontSize,Boolean bold){
    		if(fontFamily==null||fontFamily.equals("")){
    			fontFamily="宋体";
    		}
    		if(fontSize==null){
    			fontSize=16;
    		}
    		if(bold==null){
    			bold=true;
    		}
    		if(tableIndex==null){
    			tableIndex=document.getTables().size()-1;
    		}
    		if(rowIndex==null){
    			rowIndex=0;
    		}
    		if(cellIndex==null){
    			cellIndex=0;
    		}
    		XWPFTable table=document.getTables().get(tableIndex);
    		XWPFTableRow row=table.getRow(rowIndex);
    		XWPFTableCell cell=row.getCell(cellIndex);
    		addParagraphOfCell(cell, list,fontFamily,fontSize,bold);
    	} 
    	
    	public static void addParagraphOfCell(XWPFTableCell cell,List<String> list,String fontFamily,Integer fontSize,Boolean bold){
    		XWPFParagraph xwpf=null;
    		if(list!=null&&list.size()>0){
    			for (String string : list) {
    				xwpf=cell.addParagraph();
    				xwpf.setAlignment(ParagraphAlignment.CENTER);
    				XWPFRun run=xwpf.createRun();
    				run.setFontFamily(fontFamily);
    				run.setFontSize(fontSize);
    				run.setBold(bold);
    				run.setText(string);
    			}
    		}
    	}
    	
    	private static void controlTableBorder(XWPFTable ss){
    		CTTblBorders borders=ss.getCTTbl().getTblPr().addNewTblBorders();
    	    CTBorder hBorder=borders.addNewInsideH();
    	    hBorder.setVal(STBorder.Enum.forString("none"));
    	    hBorder.setSz(new BigInteger("1"));
    	    hBorder.setColor("0000FF");
    	    CTBorder vBorder=borders.addNewInsideV();
    	    vBorder.setVal(STBorder.Enum.forString("none"));
    	    vBorder.setSz(new BigInteger("1"));
    	    vBorder.setColor("00FF00");
    	    CTBorder lBorder=borders.addNewLeft();
    	    lBorder.setVal(STBorder.Enum.forString("none"));
    	    lBorder.setSz(new BigInteger("1"));
    	    lBorder.setColor("3399FF");
    	    CTBorder rBorder=borders.addNewRight();
    	    rBorder.setVal(STBorder.Enum.forString("none"));
    	    rBorder.setSz(new BigInteger("1"));
    	    rBorder.setColor("F2B11F");
    	    CTBorder tBorder=borders.addNewTop();
    	    tBorder.setVal(STBorder.Enum.forString("none"));
    	    tBorder.setSz(new BigInteger("1"));
    	    tBorder.setColor("C3599D");
    	    CTBorder bBorder=borders.addNewBottom();
    	    bBorder.setVal(STBorder.Enum.forString("none"));
    	    bBorder.setSz(new BigInteger("1"));
    	    bBorder.setColor("F7E415");
    	}
    	
    	/**
    	 * 在指定表格中增加行
    	 * @param document 文档对象
    	 * @param tableIndex 表格索引
    	 * @param rowIndex 行索引
    	 * @param datas 行数据集合
    	 * */
    	public static void addTableRow(XWPFDocument document,int tableIndex,Integer rowIndex,List<List<String>> datas){
    		addTableRow(document, tableIndex, rowIndex, datas,0);
    	}
    	/**
    	 * 在指定表格中增加行
    	 * @param document 文档对象
    	 * @param tableIndex 表格索引
    	 * @param rowIndex 行索引
    	 * @param datas 行数据集合 
    	 * @param getRowIndex 获取指定行的列数据
    	 * */
    	public static void addTableRow(XWPFDocument document,int tableIndex,Integer rowIndex,List<List<String>> datas,int getRowIndex){
    		addTableRow(document, tableIndex, rowIndex, datas, getRowIndex, null,null,null,null);
    	}
    	/**
    	 * 在指定表格中增加行
    	 * @param document 文档对象
    	 * @param tableIndex 表格索引
    	 * @param rowIndex 行索引
    	 * @param datas 行数据集合 
    	 * @param getRowIndex 获取指定行的列数据
    	 * @param align 布局方式
    	 * @param num 次数
    	 * @param fontFamily 字体
    	 * @param fontSize 大小
    	 * */
    	public static void addTableRow(XWPFDocument document,int tableIndex,Integer rowIndex,List<List<String>> datas,
    			int getRowIndex,String align,Integer num,String fontFamily,Integer fontSize){
    		if(align==null){
    			align="center";
    		}
    		boolean tag=false;
    		if(num!=null){
    			tag=true;
    		}
    		List<XWPFTable> ts=document.getTables();
    		XWPFTable ss=ts.get(tableIndex);
    	    int c1=datas.size();
    	    List<String> list=null;
    	    XWPFTableRow rw=null;
    		for (int i = c1-1; i >=0; i--) {
    			list=datas.get(i);
    			if(rowIndex==null){
    				rowIndex=ss.getRows().size();
    			}
    			XWPFTableRow rws=ss.getRow(getRowIndex);
    			rw=ss.insertNewTableRow(rowIndex);
    			List<XWPFTableCell> rss=rws.getTableCells();
    			XWPFTableCell rs=null;
    			BigInteger width=BigInteger.valueOf(20);
    			for (int j = 0; j < rss.size(); j++) {
    				width=rss.get(j).getCTTc().getTcPr().getTcW().getW();
    				rs=rw.addNewTableCell();
    				CTTcPr cellPr = rs.getCTTc().addNewTcPr();  
    				cellPr.addNewVAlign().setVal(STVerticalJc.CENTER);  
    				if(align.equals("center")){
    				}else if(align.equals("left")){
    					cellPr.addNewVAlign().setVal(STVerticalJc.TOP);
    				}else if(align.equals("right")){
    					cellPr.addNewVAlign().setVal(STVerticalJc.CENTER); 
    				}
    				//设置宽度  
    				cellPr.addNewTcW().setW(width);  
    				XWPFParagraph p=null;
    				if(rs.getParagraphs().size()==0){
    					p=rs.addParagraph();
    				}else{
    					p=rs.getParagraphs().get(0);
    				}
    				if(align.equals("center")){
    					p.setAlignment(ParagraphAlignment.CENTER);
    				}else if(align.equals("left")){
    					p.setVerticalAlignment(TextAlignment.TOP);
    					p.setAlignment(ParagraphAlignment.LEFT);  
    				}else if(align.equals("right")){
    					p.setAlignment(ParagraphAlignment.RIGHT);  
    				}
    				XWPFRun r= p.createRun();
    				if(fontFamily!=null&&!"".equals(fontFamily)){
    					r.setFontFamily(fontFamily);
    				}
    				if(fontSize!=null&&fontSize>0){
    					r.setFontSize(fontSize);
    				}
    				if(!tag){
    					r.setText(list.get(j));
    				}
    				if(tag){
    					r.setText(list.get(j));
    					for (int k = 0; k < num; k++) {
    						r.addBreak();
    					}
         	         }
    			}
    		}
    	}
    	
    	public static void addChildTableOfTwoColumn(XWPFTable table,int row,int cell,Integer num,List<List<String>> datas){
    		XWPFTableRow  xtrow=table.getRow(row);
    		XWPFTableCell xtcell=xtrow.getCell(cell);
    		XWPFTable ss=new XWPFTable(table.getCTTbl(), table.getBody());
    		/***************************************/
    		boolean tag=false;
    		if(num!=null){
    			tag=true;
    		}
    		String align="left";
    	    int c1=datas.size();
    	    List<String> list=null;
    	    XWPFTableRow rw=null;
    		for (int i = c1-1; i >=0; i--) {
    			list=datas.get(i);
    			XWPFTableRow rws=ss.getRow(0);
    			rw=ss.insertNewTableRow(0);
    			List<XWPFTableCell> rss=rws.getTableCells();
    			XWPFTableCell rs=null;
    			BigInteger width=BigInteger.valueOf(20);
    			for (int j = 0; j < rss.size(); j++) {
    				width=rss.get(j).getCTTc().getTcPr().getTcW().getW();
    				rs=rw.addNewTableCell();
    				CTTcPr cellPr = rs.getCTTc().addNewTcPr();  
    				cellPr.addNewVAlign().setVal(STVerticalJc.CENTER);  
    				if(align.equals("center")){
    				}else if(align.equals("left")){
    					cellPr.addNewVAlign().setVal(STVerticalJc.TOP);
    				}else if(align.equals("right")){
    					cellPr.addNewVAlign().setVal(STVerticalJc.CENTER); 
    				}
    				//设置宽度  
    				cellPr.addNewTcW().setW(width);  
    				XWPFParagraph p=null;
    				if(rs.getParagraphs().size()==0){
    					p=rs.addParagraph();
    				}else{
    					p=rs.getParagraphs().get(0);
    				}
    				if(align.equals("center")){
    					p.setAlignment(ParagraphAlignment.CENTER);
    				}else if(align.equals("left")){
    					p.setVerticalAlignment(TextAlignment.TOP);
    					p.setAlignment(ParagraphAlignment.LEFT);  
    				}else if(align.equals("right")){
    					p.setAlignment(ParagraphAlignment.RIGHT);  
    				}
    				XWPFRun r= p.createRun();
    				if(!tag){
    					r.setText(list.get(j));
    				}
    				if(tag){
    					r.setText(list.get(j));
    					for (int k = 0; k < num; k++) {
    						r.addBreak();
    					}
         	         }
    			}
    		}
    		/*************************************/
    		xtcell.insertTable(0, ss);
    	}
    	
    	/**
    	 * 删除表格行
    	 * @param document 文档对象
    	 * @param datas key集合(存在删除行中的key)
    	 * */
    	public static void removeTableRow(XWPFDocument document,List<String> list){
    		if(list==null||list.size()==0){
    			return;
    		}
    		String temp=null;
            Iterator<XWPFTable> itTable = document.getTablesIterator();
            Set<XWPFTableRow> rrows=null;
            while (itTable.hasNext()) {
            	boolean tag=false;
                XWPFTable table = (XWPFTable) itTable.next();
                int rcount = table.getNumberOfRows();
                rrows=new HashSet<XWPFTableRow>();
                for (int i = 0; i < rcount; i++) {
                    XWPFTableRow row = table.getRow(i);
                    List<XWPFTableCell> cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                    	temp=cell.getText();
                    	for (String string : list) {
                    		if(temp.contains(string)){
                    			rrows.add(row);
                    			tag=true;
                    		}
    					}
                    }
                }
                if(tag){
                	iterationTable(table, rrows);
                }
            }
    	} 
    	private static void iterationTable(XWPFTable table,Set<XWPFTableRow> rows ){
    		boolean tag=false;
    		 int rcount = table.getNumberOfRows();
             for (int i = 0; i < rcount; i++) {
                 XWPFTableRow row = table.getRow(i);
                 for (XWPFTableRow xwpfTableRow : rows) {
                	 if(row.equals(xwpfTableRow)){
                		 table.removeRow(i);
                		 rows.remove(xwpfTableRow);
                		 tag=true;
                		 break;
                	 }
    			}
                if(tag){
                	break;
                }
             }
             if(tag){
            	 iterationTable(table, rows);
             }
    	}
    	/**
    	 * 在指定的table后追加行数据,一行一页
    	 * @param document 文档对象
    	 * @param tableIndex 表格索引
    	 * @param datas 行数据集合
    	 * */
    	public static void appendTableRowOfPage(XWPFDocument document,int tableIndex,List<List<String>> datas){
    		appendTableRowOfPage(document, tableIndex, datas,null);
    	}
    	/**
    	 * 在指定的table后追加行数据,一行一页
    	 * @param document 文档对象
    	 * @param tableIndex 表格索引
    	 * @param datas 行数据集合
    	 * */
    	public static void appendTableRowOfPage(XWPFDocument document,int tableIndex,List<List<String>> datas,List<List<PageDataStyle>> styles){
    		Boolean tag=false;
    		if(styles!=null&&styles.size()>0){
    			tag=true;
    		}
    		
    		List<XWPFTable> ts=document.getTables();
    		XWPFTable ss=ts.get(tableIndex);
    		CTTblBorders borders=ss.getCTTbl().getTblPr().addNewTblBorders();
    	    CTBorder hBorder=borders.addNewInsideH();
    	    hBorder.setVal(STBorder.Enum.forString("none"));
    	    hBorder.setSz(new BigInteger("1"));
    	    hBorder.setColor("0000FF");
    	    CTBorder vBorder=borders.addNewInsideV();
    	    vBorder.setVal(STBorder.Enum.forString("none"));
    	    vBorder.setSz(new BigInteger("1"));
    	    vBorder.setColor("00FF00");
    	    CTBorder lBorder=borders.addNewLeft();
    	    lBorder.setVal(STBorder.Enum.forString("none"));
    	    lBorder.setSz(new BigInteger("1"));
    	    lBorder.setColor("3399FF");
    	    CTBorder rBorder=borders.addNewRight();
    	    rBorder.setVal(STBorder.Enum.forString("none"));
    	    rBorder.setSz(new BigInteger("1"));
    	    rBorder.setColor("F2B11F");
    	    CTBorder tBorder=borders.addNewTop();
    	    tBorder.setVal(STBorder.Enum.forString("none"));
    	    tBorder.setSz(new BigInteger("1"));
    	    tBorder.setColor("C3599D");
    	    CTBorder bBorder=borders.addNewBottom();
    	    bBorder.setVal(STBorder.Enum.forString("none"));
    	    bBorder.setSz(new BigInteger("1"));
    	    bBorder.setColor("F7E415");
    	    int c1=datas.size();
    	    PageDataStyle style=null;
    	    List<String> list=null;
    	    List<PageDataStyle> pdss=null;
    		for (int i = 0; i < c1; i++) {
    			XWPFTableRow rw=ss.createRow();
    			rw.setCantSplitRow(true);
    			XWPFTableCell rs=rw.getCell(0);
    			list=datas.get(i);
    			int count=44-list.size();
    			int size=list.size();
    			List<XWPFParagraph> paras=rs.getParagraphs();
    			if(tag){
    				pdss=styles.get(i);
    				XWPFParagraph txp=null;
    				for (int j=0;j<=size-1;j++) {
    					txp=rs.addParagraph();
    					XWPFRun run =txp.insertNewRun(0);
    					run.setText(list.get(j));  
    					style=pdss.get(j);
    					if(style.getBold()!=null){
    						run.setBold(style.getBold());
    					}
    					if(style.getFamily()!=null){
    						run.setFontFamily(style.getFamily());
    					}
    					if(style.getSize()!=null){
    						run.setFontSize(style.getSize());
    					}
    					if(style.getAlign()==null||style.getAlign().equals("")){
    						txp.setAlignment(ParagraphAlignment.LEFT);
    					}else if(style.getAlign().equals("center")){
    						txp.setAlignment(ParagraphAlignment.CENTER);
    					}else if(style.getAlign().equals("left")){
    						txp.setAlignment(ParagraphAlignment.LEFT);
    					}else if(style.getAlign().equals("right")){
    						txp.setAlignment(ParagraphAlignment.RIGHT);
    					}
    				}
    				for (int j=0;j<count;j++) {
    					rs.addParagraph();
    				}
    			}else{
    				for (int j=0;j<count;j++) {
    					XWPFRun run = paras.get(0).insertNewRun(0); 
    					run.setText("");  
    					run.addBreak();
    				}
    				for (int j=size-1;j>=0;j--) {
    					XWPFRun run = paras.get(0).insertNewRun(0); 
    					run.setText(list.get(j));  
    					run.addBreak();
    				}
    			}
    		}
    		ss.removeRow(0);
    	}
    	/**
    	 * 文件复制
    	 * */
    	 public static boolean copyFile(String fileFrom, String fileTo) {  
    		 FileInputStream in =null;
    		 FileOutputStream out =null;
    		 	try {  
    	            in = new java.io.FileInputStream(fileFrom);  
    	            out = new FileOutputStream(fileTo);  
    	            byte[] bt = new byte[1024];  
    	            int count;  
    	            while ((count = in.read(bt)) > 0) {  
    	                out.write(bt, 0, count);  
    	            }  
    	            return true;  
    	        } catch (IOException ex) {  
    	            return false;  
    	        }finally{
    	        	if(in!=null){
    	        		try {
    						in.close();
    					} catch (IOException e) {
    						// TODO Auto-generated catch block
    						log.error("失败!", e);
    					}  
    	        	}
    	        	if(out!=null){
    	        		try {
    						out.close();
    					} catch (IOException e) {
    						// TODO Auto-generated catch block
    						log.error("失败!", e);
    					} 
    	        	}
    	        }  
    	    }  
    	 
    	 public static void addParagraphOfTable(XWPFDocument document,Integer tableIndex,
    				Integer rowIndex,Integer cellIndex,List<FontStyle> list,Boolean centerTag){
    		 if(centerTag==null){
    			 centerTag=false;
    		 }
    		if(tableIndex==null){
    			tableIndex=document.getTables().size()-1;
    		}
    		if(rowIndex==null){
    			rowIndex=0;
    		}
    		if(cellIndex==null){
    			cellIndex=0;
    		}
    		XWPFTable table=document.getTables().get(tableIndex);
    		XWPFTableRow row=table.getRow(rowIndex);
    		XWPFTableCell cell=row.getCell(cellIndex);
    		addParagraphOfCell(cell, list,centerTag);
    	} 
    	
    	public static void addParagraphOfCell(XWPFTableCell cell,List<FontStyle> list,Boolean centerTag){
    		XWPFParagraph xwpf=null;
    		if(list!=null&&list.size()>0){
    			for (FontStyle font : list) {
    				xwpf=cell.addParagraph();
    				if(centerTag){
    					xwpf.setAlignment(ParagraphAlignment.CENTER);
    				}
    				XWPFRun run=xwpf.createRun();
    				run.setFontFamily(font.getFontFamily());
    				run.setFontSize(font.getFontSize());
    				run.setBold(font.getBold());
    				run.setText(font.getText());
    			}
    		}
    	}
    	/**
    	 * 表格插入图片
    	 * @param document
    	 * @param map
    	 * @param doc
    	 * @param index
    	 */
    	public static void replaceImgager( XWPFParagraph paragraph,Map<String, Object> map,ImagerXWPFDocument doc){
    		try {
    	        int width = Integer.parseInt(map.get("width").toString()); 
    	        int height = Integer.parseInt(map.get("height").toString()); 
    	        int picType = getPictureType(map.get("type").toString()); 
    	        byte[] byteArray = (byte[]) map.get("content"); 
    	        ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);
    	        String blipId = doc.addPictureData(byteInputStream,picType);
    	        int ind =doc.getNextPicNameNumber(getPictureType(map.get("type").toString()));
    	        doc.createPicture(blipId,ind, width , height,paragraph);
    		} catch (Exception e) {
    			log.error("失败!", e);
    		}
    	}
    	public static void addImagerRow(XWPFTable table,int rowIndex,int getRowIndex){
    	    XWPFTableRow rw=null;
    		XWPFTableRow rws=table.getRow(getRowIndex);
    		rw=table.insertNewTableRow(rowIndex);
    		List<XWPFTableCell> rss=rws.getTableCells();
    		XWPFTableCell rs=null;
    		BigInteger width=BigInteger.valueOf(20);
    		for (int j = 0; j < rss.size(); j++) {
    			width=rss.get(j).getCTTc().getTcPr().getTcW().getW();
    			rs=rw.addNewTableCell();
    			CTTcPr cellPr = rs.getCTTc().addNewTcPr();  
    			cellPr.addNewVAlign().setVal(STVerticalJc.CENTER);  
    			//设置宽度  
    			cellPr.addNewTcW().setW(width); 
    			XWPFParagraph p=null;
    			if(rs.getParagraphs().size()==0){
    				p=rs.addParagraph();
    			}else{
    				p=rs.getParagraphs().get(0);
    			}
    			p.setAlignment(ParagraphAlignment.CENTER);
    		}
    	}
    	   /**
      * 根据图片类型,取得对应的图片类型代码 
      * @param picType 
      * @return int 
      */ 
     public static int getPictureType(String picType){  
         int res = ImagerXWPFDocument.PICTURE_TYPE_PICT;  
         if(picType != null){ 
             if(picType.equalsIgnoreCase("png")){ 
                 res = ImagerXWPFDocument.PICTURE_TYPE_PNG;  
             }else if(picType.equalsIgnoreCase("dib")){ 
                 res = ImagerXWPFDocument.PICTURE_TYPE_DIB;  
             }else if(picType.equalsIgnoreCase("emf")){ 
                 res = ImagerXWPFDocument.PICTURE_TYPE_EMF;  
             }else if(picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")){ 
                 res = ImagerXWPFDocument.PICTURE_TYPE_JPEG;  
             }else if(picType.equalsIgnoreCase("wmf")){ 
                 res = ImagerXWPFDocument.PICTURE_TYPE_WMF;  
             } 
         } 
         return res;  
     } 
     /**
      * 将输入流中的数据写入字节数组 
      * @param in 
      * @return 
      */ 
     public static byte[] inputStream2ByteArray(InputStream in,boolean isClose){  
         byte[] byteArray = null; 
         try{  
             int total = in.available();  
             byteArray = new byte[total]; 
             in.read(byteArray); 
         }catch(IOException e) {  
             log.error("失败!", e); 
         }finally{ 
             if(isClose){ 
                 try{  
                     in.close(); 
                 }catch(Exception e2) { 
                 	e2.printStackTrace();
                 } 
             } 
         } 
         return byteArray;  
     }
    }
    

     

     

     

     

     

     

     

    展开全文
  • ![图片说明](https://img-ask.csdn.net/upload/201607/23/1469241418_405188.png)
  • POI导出word文档模版直接用于下载和html页面展示

    Java POI导出word模板,POI转化word为html代码

    需求起因
    做项目的时候按照客户需求在系统上填写一些数据,这些数据最后要导出为word文档存档,文档有严格的样式,主要是表格构成。参考相关代码后github上找到了一个POI操作word并导出的开源项目,github地址点击前往。话不多说看结果。
    源文档
    这是下发的文件
    模板文档
    对照源文档修改自己的模板,后面会详细介绍模板的构造。
    模板文档
    系通填写界面
    做出的系统
    最终导出的文档
    导出的效果
    具体实现
    首先这功能分三部分,1.要导出的模板,2.代码 获取数据,对数据封装,填充到模板文件。3.导出要下载的文档。
    1.要导出的模板
    拿到源文档后,找到要改变的地方,这里拿一个测试文档test.docx举例。比如说我们要导出各个地区的气象数据,每个地区都可以导出,这时候就可以抽出一个模板来(有做过短信模板的这里一目了然,一模一样)。
    在这里插入图片描述
    这个文档里红色的部分要改成可变的,可能是浙江省,江苏省等其他省份信息,这时候抽取要改变的地方用双大括号加变量名代替。eg:{{value}}。
    这份文档就可以改为如下样式
    在这里插入图片描述
    2.代码实现
    这里用的是spring boot框架,maven管理依赖包,首先导入需要的依赖包

    <dependency>
      <groupId>com.deepoove</groupId>
      <artifactId>poi-tl</artifactId>
      <version>1.5.0</version>
    </dependency>
    

    下面是核心的代码

     @RequestMapping("/word")
        @ResponseBody
        public ResultJson uploadImg() {
            Map<String, Object> data = new HashMap<>();//通过map存放要填充的数据
            data.put("province","浙江省");//把每项数据写进map,key的命名要与word里面的一样
            data.put("temp",27.8);
            data.put("shidu",33.3);
            
            data.put("water",220);
            data.put("windir","西北风");
            data.put("winforce","7-8");
            data.put("chuanyi","天气热,适合T恤短裤");
            data.put("chuxing","太阳光强,宜做好防晒");
            data.put("advice1","适合海边游玩降温");
            data.put("advice2","适合洗车");
            data.put("advice3","不宜长时间吹空调");
            data.put("date", DateUtils.getCurDate());
            XWPFTemplate template = XWPFTemplate.compile("D:\\test.docx").render(data);//调用模板,填充数据
            try {
                FileOutputStream out = new FileOutputStream("D:\\天气预报.docx");//要导出的文件名
                template.write(out);
                out.flush();
                out.close();
                template.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    

    代码非常简单,就一个map搞定,这里我只是在controller里面随便测试的,真正要用当然要把这些字段放到实体来然后通过反向映射解析对象,循环填充。
    用postman请求一下,看一下导出的效果。
    在这里插入图片描述
    在这里插入图片描述
    以上就是全部过程,如果要下载直接通过response把数据流返给前端就OK了。

    原本到这里就结束了,但是用户有来了一个需求,需要预览文档,这里大家就会说了,直接转成json扔给前端处理就好了。如果说文档规则的话其实前端通过table很简单就画出来了,就怕样式很复杂,画起来非常麻烦。这里在提供一个直接将word转为html代码的方法。(做后端的我就是这么心疼前端)
    引入依赖包

        <!--poi转化-->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>3.14</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-scratchpad</artifactId>
                <version>3.14</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>3.14</version>
            </dependency>
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.poi.xwpf.converter.xhtml</artifactId>
                <version>2.0.1</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml-schemas</artifactId>
                <version>3.14</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>ooxml-schemas</artifactId>
                <version>1.3</version>
            </dependency>
    

    好像包有点多。。。。。。。。。

    实现代码

    try {
            InputStream in = new FileInputStream(new File("D:\\天气预报.docx"));//要转化的word
            XWPFDocument document = new XWPFDocument(in);
            OutputStream baos = new ByteArrayOutputStream();
            XHTMLConverter xhtmlConverter = (XHTMLConverter) XHTMLConverter.getInstance();
            xhtmlConverter.convert(document, baos,null);
            String content = baos.toString();//转化好的html代码
            baos.close();
            return ResultJson.returnRightObj(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    

    最终效果
    在这里插入图片描述
    代码返给前端展示就好了,跟word一模一样。

    END

    展开全文
  • POI结构与常用类 Apache POI是Apache软件基金会的开源项目,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。 .NET的开发人员则可以利用NPOI (POI for .NET) 来存取 Microsoft Office文档的功能。 ...

    POI结构与常用类

    Apache POI是Apache软件基金会的开源项目,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。 .NET的开发人员则可以利用NPOI (POI for .NET) 来存取 Microsoft Office文档的功能。

    包名称说明

    • HSSF提供读写Microsoft Excel XLS格式档案的功能。
    • XSSF提供读写Microsoft Excel OOXML XLSX格式档案的功能。
    • HWPF提供读写Microsoft Word DOC格式档案的功能。
    • HSLF提供读写Microsoft PowerPoint格式档案的功能。
    • HDGF提供读Microsoft Visio格式档案的功能。
    • HPBF提供读Microsoft Publisher格式档案的功能。
    • HSMF提供读Microsoft Outlook格式档案的功能。

     

    测试例子

    测试模板:

     

    测试代码:

    @Test
        public void docxExportTest() throws IOException {
            InputStream is = null;
            FileOutputStream fos = null;
            try {
                //获取docx解析对象
                is = new FileInputStream("F:\\document\\咨询服务合同.docx");
                XWPFDocument document = new XWPFDocument(is);
    
                //组装参数
                File seal = new File("F:\\imgtest\\1.jpg");
                Map<String, Object> sealMap = new HashMap<String, Object>();
                sealMap.put("width", 50);
                sealMap.put("height", 50);
                sealMap.put("type", "jpg");
                sealMap.put("content", new FileInputStream(seal));
    
                Map<String, Object> contentMap = new HashMap<>();
                contentMap.put("part_a", "张三");
                contentMap.put("address_a", "青岛市市南区动漫产业园E座");
                contentMap.put("legal_person_a", "李四");
                contentMap.put("seal", sealMap);
    
                //解析替换段落文本对象
                XWPFUtil.changeParagraph(document, contentMap);
    
                //生成新的word文档
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String fileName = "咨询服务合同" + sdf.format(new Date()) + ".docx";
                File file = new File("F://" + fileName);
                fos = new FileOutputStream(file);
                document.write(fos);
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (is != null) {
                    is.close();
                }
                if (fos != null) {
                    fos.close();
                }
            }
        }

    工具类:

    package com.m2plat.puhui.utils;
    
    import com.alibaba.fastjson.JSON;
    import org.apache.commons.io.IOUtils;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    import org.apache.poi.xwpf.usermodel.XWPFRun;
    import org.apache.xmlbeans.XmlException;
    import org.apache.xmlbeans.XmlToken;
    import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
    import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
    import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.core.io.ClassPathResource;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.List;
    import java.util.Map;
    
    /**
     * Created by xiangzh on 2018/11/1.
     */
    public class XWPFUtils {
    
        private static Logger logger = LoggerFactory.getLogger(XWPFUtils.class);
    
        /**
         * 根据模板生成word文档
         * @param os
         * @param tempPath
         * @param contentMap
         */
        public static void writeTemp(OutputStream os, String tempPath, Map<String, Object> contentMap){
            logger.info("---根据模板生成word文档");
            logger.info("---模板地址:{}",tempPath);
            logger.info("---替换内容:{}", JSON.toJSONString(contentMap));
            ClassPathResource resource = new ClassPathResource(tempPath);
            if(resource == null || !resource.exists()){
                logger.error("---模板文件不存在,tempPath:{}",tempPath);
                return;
            }
    
            InputStream is = null;
            try{
                is = resource.getInputStream();
                XWPFDocument document = new XWPFDocument(is);
                XWPFUtils.changeParagraph(document, contentMap);
                //生成新的word文档
                document.write(os);
            }catch (IOException e){
                logger.error("---输出word文档失败,原因:{}",e.getMessage());
            }finally {
                IOUtils.closeQuietly(is);
            }
        }
    
    
        /**
         * 替换段落文本
         *
         * @param document docx解析对象
         * @param textMap  需要替换的信息集合
         */
        public static void changeParagraph(XWPFDocument document, Map<String, Object> textMap) {
            //获取段落集合
            List<XWPFParagraph> paragraphs = document.getParagraphs();
    
            for (XWPFParagraph paragraph : paragraphs) {
                List<XWPFRun> runs = paragraph.getRuns();
                for (XWPFRun run : runs) {
                    String text = run.getText(0);
                    //判断文本是否需要进行替换
                    if (checkText(text)) {
                        for (Map.Entry<String, Object> entry : textMap.entrySet()) {
                            //匹配模板与替换值 格式${key}
                            String key = "${" + entry.getKey() + "}";
                            Object value = entry.getValue();
    
                            if (text.contains(key)) {
                                if (value instanceof String) { //文字替换
                                    text = text.replace(key, (String) value);
                                } else if (value instanceof Map) { //图片替换
                                    text = text.replace(key, "");
                                    Map picMap = (Map) value;
                                    int width = Integer.parseInt(picMap.get("width").toString());
                                    int height = Integer.parseInt(picMap.get("height").toString());
                                    int picType = getPictureType(picMap.get("type").toString());
                                    FileInputStream fis = (FileInputStream) picMap.get("content");
                                    try {
                                        String blipId = document.addPictureData(fis, picType);
                                        int id = document.getNextPicNameNumber(picType);
                                        XWPFUtils.createPicture(id, blipId, width, height, run);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }
                        //替换模板原来位置
                        run.setText(text, 0);
                    }
                }
            }
        }
    
        /**
         * @param id
         * @param blipId
         * @param width 宽
         * @param height 高
         //* @param paragraph  段落
         */
        private static void createPicture(int id, String blipId, int width, int height,XWPFRun xwpfRun) {
            final int EMU = 9525;
            width *= EMU;
            height *= EMU;
            CTInline inline = xwpfRun.getCTR().addNewDrawing().addNewInline();
            //CTInline inline = paragraph.createRun().getCTR().addNewDrawing().addNewInline(); //在遍历run列表的时候,创建新的run有可能会导致报错
            String picXml = ""
                    + "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"
                    + "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
                    + "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
                    + "         <pic:nvPicPr>" + "            <pic:cNvPr id=\""
                    + id
                    + "\" name=\"Generated\"/>"
                    + "            <pic:cNvPicPr/>"
                    + "         </pic:nvPicPr>"
                    + "         <pic:blipFill>"
                    + "            <a:blip r:embed=\""
                    + blipId
                    + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>"
                    + "            <a:stretch>"
                    + "               <a:fillRect/>"
                    + "            </a:stretch>"
                    + "         </pic:blipFill>"
                    + "         <pic:spPr>"
                    + "            <a:xfrm>"
                    + "               <a:off x=\"0\" y=\"0\"/>"
                    + "               <a:ext cx=\""
                    + width
                    + "\" cy=\""
                    + height
                    + "\"/>"
                    + "            </a:xfrm>"
                    + "            <a:prstGeom prst=\"rect\">"
                    + "               <a:avLst/>"
                    + "            </a:prstGeom>"
                    + "         </pic:spPr>"
                    + "      </pic:pic>"
                    + "   </a:graphicData>" + "</a:graphic>";
    
            inline.addNewGraphic().addNewGraphicData();
            XmlToken xmlToken = null;
            try {
                xmlToken = XmlToken.Factory.parse(picXml);
            } catch (XmlException xe) {
                xe.printStackTrace();
            }
            inline.set(xmlToken);
    
            inline.setDistT(0);
            inline.setDistB(0);
            inline.setDistL(0);
            inline.setDistR(0);
    
            CTPositiveSize2D extent = inline.addNewExtent();
            extent.setCx(width);
            extent.setCy(height);
    
            CTNonVisualDrawingProps docPr = inline.addNewDocPr();
            docPr.setId(id);
            docPr.setName("docx_img_ " + id);
            docPr.setDescr("docx Picture");
        }
    
        /**
         * 判断文本中是否包含$
         *
         * @param text 文本
         * @return 包含返回true, 不包含返回false
         */
        private static boolean checkText(String text) {
            if (text == null || "".equals(text)) {
                return false;
            }
            return text.contains("$");
        }
    
        /**
         * 根据图片类型,取得对应的图片类型代码
         *
         * @param picType
         * @return int
         */
        private static int getPictureType(String picType) {
            int res = XWPFDocument.PICTURE_TYPE_PICT;
            if (picType != null) {
                if (picType.equalsIgnoreCase("png")) {
                    res = XWPFDocument.PICTURE_TYPE_PNG;
                } else if (picType.equalsIgnoreCase("dib")) {
                    res = XWPFDocument.PICTURE_TYPE_DIB;
                } else if (picType.equalsIgnoreCase("emf")) {
                    res = XWPFDocument.PICTURE_TYPE_EMF;
                } else if (picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")) {
                    res = XWPFDocument.PICTURE_TYPE_JPEG;
                } else if (picType.equalsIgnoreCase("wmf")) {
                    res = XWPFDocument.PICTURE_TYPE_WMF;
                }
            }
            return res;
        }
    }
    View Code

    测试结果:

     

    注意事项

    1.实际开发过程中,模板通常存放在项目工程中,获取模板的代码如下:

    String tempPath = "static/exportTemplates/咨询服务合同.docx";
    ClassPathResource resource = new ClassPathResource(tempPath);
    InputStream is = resource.getInputStream();
    XWPFDocument document = new XWPFDocument(is);

    2.导出文件时如果报错:Failed to read zip entry source,是因为打包编译将文件解压缩导致出问题,解决办法为在pom文件中配置nonFilteredFileExtension:

    <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>2.6</version>
                    <configuration>
                        <delimiters>
                            <delimiter>@</delimiter>
                            <delimiter>${*}</delimiter>
                        </delimiters>
                        <useDefaultDelimiters>false</useDefaultDelimiters>
                        <encoding>UTF-8</encoding><!-- 指定编码格式,否则在DOS下运行mvn命令时当发生文件资源copy时将使用系统默认使用GBK编码 -->
                        <nonFilteredFileExtensions>
                            <nonFilteredFileExtension>bar</nonFilteredFileExtension>
                            <nonFilteredFileExtension>zip</nonFilteredFileExtension>
                            <nonFilteredFileExtension>txt</nonFilteredFileExtension>
                            <nonFilteredFileExtension>pdf</nonFilteredFileExtension>
                            <nonFilteredFileExtension>ttf</nonFilteredFileExtension>
                            <nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
                            <nonFilteredFileExtension>xls</nonFilteredFileExtension>
                            <nonFilteredFileExtension>docx</nonFilteredFileExtension>
                            <nonFilteredFileExtension>doc</nonFilteredFileExtension>
                        </nonFilteredFileExtensions>
                    </configuration>
                </plugin>

     3.所有导出参数必须转换成string类型后才能导出,否则替换不了。

     

     

     

    参考:

    POI使用详解

    POI通过XWPFDocument方式操作word2007

    POI操作word模板并生成新的word.docx

    war在服务器上读取文件报:java.io.IOException: Failed to read zip entry source

    SpringBoot打成jar包后,读取resources目录下的文件

    在Springboot中从项目中读取文件并下载时 ResourceUtils.getFile返回路径出错并解决

    转载于:https://www.cnblogs.com/Jason-Xiang/p/10001176.html

    展开全文
  • 标题 使用poi导出word文件 项目需求:需要将数据按照一定的格式导出成word文档。文本替换,表格循环(表格内部行循环,整个表格循环),插入图片等。 参考连接:...
  • poi使用模板导出word带图片

    千次阅读 2016-11-15 16:17:05
    1.下面是我做的加载模板导出带图片的word的导出方式,使用之前请映入freemarker的jar包,可以从百度下载即可。 2.首先准备到你要导出的word模板,在要填充的模板中填入el表达式,如下图所示。 XXXX公司招聘高校毕业...
  • word模板模板在项目中的存放位置: 直接上代码: /** * * 对docx文件中的文本及表格中的内容进行替换 --模板仅支持对 {key} 标签的替换 * * @ClassName: WordTemplate * @Description: TODO(!!!使用word...
  • 需求:根据一个word模板,在程序中替换模板中的参数,然后根据这个模板导出word文件。 引入POI对word操作的依赖: <dependency> <groupId>org.apache.poi</groupId> <artifactId>...
  • poi导出word模板

    2020-03-30 10:53:14
    **poi导出word模板段落处理 流程: 1:读取文档:` //获取docx解析对象 XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl)); 在XWPFDocument对象里有两个常用的方法,一个是...
  • POI之根据模板导出word-yellowcong

    千次阅读 2017-11-21 16:46:19
    根据模版导出word这个东西在实际开发中,是很常用的,我今天遇到坑了,就是如何根据word模版生成word。网上的代码好多都是坑爹,不是缺环境,就是却方法,所以我自己做了一个小例子。如果希望有图片替换的教程,大家...

空空如也

1 2 3 4 5 ... 18
收藏数 349
精华内容 139
关键字:

poi模板导出word