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的时候很不友好,容易将你写的东西分割,无语。

POI模板导出word_第1张图片



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();

    }
}












你可能感兴趣的:(java,poi,模板,word,导出)