精华内容
下载资源
问答
  • 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();
    
        }
    }
    
    











    展开全文
  • POI XWPFDocument 导出word目录详解

    千次阅读 2019-09-26 14:24:18
    通过XWPFDocument生成目录 ...按照顺序,只能在word写入所有内容后在掉createTOC()生成目录,导致目录在最下方 下面我们重写createTOC()来完成对目录样式,布局,标题,位置的修改 /** * 生成目...

    完整代码,代码为main方法直接运行,该代码实现了对目录样式,布局,标题,位置的修改,但是无法自动获取页码,只可以手动添加目录中对应的页码,或者设置为空。下方资源运行环境:

    1. Windows10
    2. JDK1.8
    3. org.apache.poi-3.14

    通过XWPFDocument生成目录

    正常情况下,通过XWPFDocument自带的createTOC(),可以生成目录,但是有一些缺点:

    1. 目录标题无法更改,只能显示英文
    2. 样式不够美观,无法布局
    3. 按照顺序,只能在word中写入所有内容后在掉createTOC()生成目录,导致目录在最下方

    下面我们重写createTOC()来完成对目录样式,布局,标题,位置的修改

     /**
         * 生成目录
         * @param doc
         */
        public static void createTOC(XWPFDocument doc) {
            CTSdtBlock block = doc.getDocument().getBody().addNewSdt();
            ExportWord toc = new ExportWord(block);
    
            /*当前位置调用添加正文的方法,需要传参XWPFDocumen对象*/
            writeAllNews(doc);
    
            List<XWPFParagraph> paragraphs = doc.getParagraphs();
            for (XWPFParagraph par : paragraphs) {
                String parStyle = par.getStyle();
                if (parStyle != null && parStyle.startsWith("Heading")) {
    
                    //获取书签,书签的对应关系很重要,关系到目录能否正常跳转
                    List<CTBookmark> bookmarkList = par.getCTP().getBookmarkStartList();
                    try {
                        int level = Integer.parseInt(parStyle.substring("Heading".length()));
    
                        //添加标题
                        toc.addRow(level, par.getText(), 1, bookmarkList.get(0).getName());
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    

    上方就是重写后的代码,首先将目录标题占位在最上方,接着进行内容的写入,最后进行目录的成。

    展开全文
  • import java.io.ByteArrayInputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import org.apache.poi.poifs.filesystem....import org.apache.poi.poifs.fil...

    import java.io.ByteArrayInputStream;

    import java.io.File;

    import java.io.FileOutputStream;

    import java.io.IOException;

    import org.apache.poi.poifs.filesystem.DirectoryEntry;

    import org.apache.poi.poifs.filesystem.DocumentEntry;

    import org.apache.poi.poifs.filesystem.POIFSFileSystem;

    public class Main {

    public static void main(String[] args) {

    boolean w = false;

    String path = "d:/";

    try {

    if (!"".equals(path)) {

    // 检查目录是否存在

    File fileDir = new File(path);

    if (fileDir.exists()) {

    // 生成临时文件名称

    String fileName = "a.doc";

    String content = "

    " +

    "制度发布通知

    ";

    byte b[] = content.getBytes();

    ByteArrayInputStream bais = new ByteArrayInputStream(b);

    POIFSFileSystem poifs = new POIFSFileSystem();

    DirectoryEntry directory = poifs.getRoot();

    DocumentEntry documentEntry = directory.createDocument("WordDocument", bais);

    FileOutputStream ostream = new FileOutputStream(path+ fileName);

    poifs.writeFilesystem(ostream);

    bais.close();

    ostream.close();

    }

    }

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

    展开全文
  • 1.引入word导出所需依赖包 工作常用的excel,word导出,需要引入下面的6个主要包,和主要包依赖的其他包 ,可以看下面的表格进行依赖下载引入 这下面的两张图是主要包对应涉及到功能,可以按需要进行引入,有些真的...

    1.引入word导出所需依赖包

    工作常用的excel,word导出,需要引入下面的6个主要包,和主要包依赖的其他包 ,可以看下面的表格进行依赖下载引入
    在这里插入图片描述
    这下面的两张图是主要包对应涉及到功能,可以按需要进行引入,有些真的用不到的主要包可以不引入
    在这里插入图片描述
    在这里插入图片描述

    2.引入工具类

    1.util类

    package com.management.util;
    
    import org.apache.poi.POIXMLDocument;
    import org.apache.poi.xwpf.usermodel.*;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
    
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.*;
    
    /**
     * Created by wfg 2020-08-12
     */
    public class ExportWordUtil {
        /**
         * 根据模板生成word文档
         * @param inputUrl 模板路径
         * @param textMap 需要替换的文本内容
         * @param mapList 需要动态生成的内容
         * @return
         */
        public static CustomXWPFDocument changWord(String inputUrl, Map<String, Object> textMap, List<Object> mapList,int[] placeList) {
            CustomXWPFDocument document = null;
            try {
                //获取docx解析对象
                document = new CustomXWPFDocument(POIXMLDocument.openPackage(inputUrl));
    
                //解析替换文本段落对象
                ExportWordUtil.changeText(document, textMap);
    
                //解析替换表格对象
                ExportWordUtil.changeTable(document, textMap, mapList,placeList);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return document;
        }
    
        /**
         * 替换段落文本
         * @param document docx解析对象
         * @param textMap 需要替换的信息集合
         */
        public static void changeText(CustomXWPFDocument document, Map<String, Object> textMap){
            //获取段落集合
            List<XWPFParagraph> paragraphs = document.getParagraphs();
    
            for (XWPFParagraph paragraph : paragraphs) {
                //判断此段落时候需要进行替换
                String text = paragraph.getText();
                if(checkText(text)){
                    List<XWPFRun> runs = paragraph.getRuns();
                    for (XWPFRun run : runs) {
                        //替换模板原来位置
                        Object ob = changeValue(run.toString(), textMap);
                        System.out.println("段落:"+run.toString());
                        if (ob instanceof String){
                            run.setText((String)ob,0);
                        }
                    }
                }
            }
        }
    
        /**
         * 替换表格对象方法
         * @param document docx解析对象
         * @param textMap 需要替换的信息集合
         * @param mapList 需要动态生成的内容
         */
        public static void changeTable(CustomXWPFDocument document, Map<String, Object> textMap, List<Object> mapList,int[] placeList){
            //获取表格对象集合
            List<XWPFTable> tables = document.getTables();
    
            //循环所有需要进行替换的文本,进行替换
            for (int i = 0; i < tables.size(); i++) {
                System.out.println("1111");
                XWPFTable table = tables.get(i);
                if(checkText(table.getText())){
                    System.out.println("222");
                    List<XWPFTableRow> rows = table.getRows();
                    System.out.println("简单表格替换:"+rows);
                    //遍历表格,并替换模板
                    eachTable(document,rows, textMap);
                }
            }
    
            int index=0;
            //操作word中的表格
            for (int i = 0; i < tables.size(); i++) {
                //只处理行数大于等于2的表格,且不循环表头
                XWPFTable table = tables.get(i);
                if(placeList[index]==i){
                    List<String[]> list = (List<String[]>) mapList.get(index);
                    //第二个表格使用daList,插入数据
                    if (null != list && 0 < list.size()){
                        insertTable(table, null,list,2);
                        List<Integer[]> indexList = startEnd(list);
                        for (int c=0;c<indexList.size();c++){
                            //合并行
                            mergeCellVertically(table,0,indexList.get(c)[0]+1,indexList.get(c)[1]+1);
                        }
                    }
                    index++;
                }
    
            }
        }
        /**
         * 遍历表格
         * @param rows 表格行对象
         * @param textMap 需要替换的信息集合
         */
        public static void eachTable(CustomXWPFDocument document, List<XWPFTableRow> rows , Map<String, Object> textMap){
            for (XWPFTableRow row : rows) {
                List<XWPFTableCell> cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    //判断单元格是否需要替换
                    if(checkText(cell.getText())){
                        List<XWPFParagraph> paragraphs = cell.getParagraphs();
                        for (XWPFParagraph paragraph : paragraphs) {
                            List<XWPFRun> runs = paragraph.getRuns();
                            for (XWPFRun run : runs) {
                                Object ob = changeValue(run.toString(), textMap);
                                if (ob instanceof String){
                                    run.setText((String)ob,0);
                                }else if (ob instanceof Map){
                                    run.setText("",0);
                                    Map pic = (Map)ob;
                                    int width = Integer.parseInt(pic.get("width").toString());
                                    int height = Integer.parseInt(pic.get("height").toString());
                                    int picType = getPictureType(pic.get("type").toString());
                                    byte[] byteArray = (byte[]) pic.get("content");
                                    ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);
                                    try {
                                        //String ind = document.addPictureData(byteInputStream,picType);
                                        //document.createPicture(ind, width , height,paragraph);
                                        String ind = document.addPictureData(byteInputStream, picType);
                                        int id = document.getNextPicNameNumber(picType);
                                        document.createPicture(ind, id, width, height, paragraph);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    
        /**
         * 为表格插入数据,行数不够添加新行
         * @param table 需要插入数据的表格
         * @param tableList 第四个表格的插入数据
         * @param daList 第二个表格的插入数据
         * @param type 表格类型:1-第一个表格 2-第二个表格 3-第三个表格 4-第四个表格
         */
        public static void insertTable(XWPFTable table, List<String> tableList,List<String[]> daList,Integer type){
            if (2 == type){
                //创建行和创建需要的列
                for(int i = 1; i < daList.size(); i++){
                    //添加一个新行
                    XWPFTableRow row = table.insertNewTableRow(1);
                    /*System.out.println("333");
                    System.out.println(table.getRow(1).getHeight());*/
                    for(int k=0; k<daList.get(0).length;k++){
                        row.createCell();//根据String数组第一条数据的长度动态创建列
                    }
                    row.setHeight(400);//设置行高度
                }
    
                //创建行,根据需要插入的数据添加新行,不处理表头
                for(int i = 0; i < daList.size(); i++){
                    table.getRow(i+1).setHeight(400);//设置行高度
                    List<XWPFTableCell> cells = table.getRow(i+1).getTableCells();
                    for(int j = 0; j < cells.size(); j++){
                        XWPFTableCell cell02 = cells.get(j);
                        cell02.setText(daList.get(i)[j]);
                        /** 设置水平居中 */
                        CTTc cttc = cell02.getCTTc();
                        CTTcPr ctPr = cttc.addNewTcPr();
                        ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);
                        cttc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
                    }
                }
            }else if (4 == type){
                //插入表头下面第一行的数据
                for(int i = 0; i < tableList.size(); i++){
                    XWPFTableRow row = table.createRow();
                    row.setHeight(400);//设置行高度
                    List<XWPFTableCell> cells = row.getTableCells();
                    cells.get(0).setText(tableList.get(i));
                }
            }
        }
    
        /**
         * 判断文本中时候包含$
         * @param text 文本
         * @return 包含返回true,不包含返回false
         */
        public static boolean checkText(String text){
            boolean check  =  false;
            if(text.indexOf("$")!= -1){
                check = true;
            }
            return check;
        }
    
        /**
         * 匹配传入信息集合与模板
         * @param value 模板需要替换的区域
         * @param textMap 传入信息集合
         * @return 模板需要替换区域信息集合对应值
         */
        public static Object changeValue(String value, Map<String, Object> textMap){
            Set<Map.Entry<String, Object>> textSets = textMap.entrySet();
            Object valu = "";
            for (Map.Entry<String, Object> textSet : textSets) {
                //匹配模板与替换值 格式${key}
                String key = textSet.getKey();
                if(value.indexOf(key)!= -1){
                    valu = textSet.getValue();
                }
            }
            return valu;
        }
    
        /**
         * 将输入流中的数据写入字节数组
         * @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) {
                e.printStackTrace();
            }finally{
                if(isClose){
                    try {
                        in.close();
                    } catch (Exception e2) {
                        System.out.println("关闭流失败");
                    }
                }
            }
            return byteArray;
        }
    
        /**
         * 根据图片类型,取得对应的图片类型代码
         * @param picType
         * @return int
         */
        private static int getPictureType(String picType){
            int res = CustomXWPFDocument.PICTURE_TYPE_PICT;
            if(picType != null){
                if(picType.equalsIgnoreCase("png")){
                    res = CustomXWPFDocument.PICTURE_TYPE_PNG;
                }else if(picType.equalsIgnoreCase("dib")){
                    res = CustomXWPFDocument.PICTURE_TYPE_DIB;
                }else if(picType.equalsIgnoreCase("emf")){
                    res = CustomXWPFDocument.PICTURE_TYPE_EMF;
                }else if(picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")){
                    res = CustomXWPFDocument.PICTURE_TYPE_JPEG;
                }else if(picType.equalsIgnoreCase("wmf")){
                    res = CustomXWPFDocument.PICTURE_TYPE_WMF;
                }
            }
            return res;
        }
    
        /**
         * 合并行
         * @param table
         * @param col 需要合并的列
         * @param fromRow 开始行
         * @param toRow 结束行
         */
        public static void mergeCellVertically(XWPFTable table, int col, int fromRow, int toRow) {
            for(int rowIndex = fromRow; rowIndex <= toRow; rowIndex++){
                CTVMerge vmerge = CTVMerge.Factory.newInstance();
                if(rowIndex == fromRow){
                    vmerge.setVal(STMerge.RESTART);
                } else {
                    vmerge.setVal(STMerge.CONTINUE);
                }
                XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
                CTTcPr tcPr = cell.getCTTc().getTcPr();
    
                if (tcPr != null) {
                    tcPr.setVMerge(vmerge);
                    //cell.getCTTc().setTcPr(tcPr);
                } else {
                    tcPr = CTTcPr.Factory.newInstance();
                    tcPr.setVMerge(vmerge);
                    cell.getCTTc().setTcPr(tcPr);
                }
            }
        }
        /**
         * 获取需要合并单元格的下标
         * @return
         */
        public static List<Integer[]> startEnd(List<String[]> daList){
            List<Integer[]> indexList = new ArrayList<Integer[]>();
    
            List<String> list = new ArrayList<String>();
            for (int i=0;i<daList.size();i++){
                list.add(daList.get(i)[0]);
            }
            Map<Object, Integer> tm = new HashMap<Object, Integer>();
            for (int i=0;i<daList.size();i++){
                if (!tm.containsKey(daList.get(i)[0])) {
                    tm.put(daList.get(i)[0], 1);
                } else {
                    int count = tm.get(daList.get(i)[0]) + 1;
                    tm.put(daList.get(i)[0], count);
                }
            }
            for (Map.Entry<Object, Integer> entry : tm.entrySet()) {
                String key = entry.getKey().toString();
                String value = entry.getValue().toString();
                if (list.indexOf(key) != (-1)){
                    Integer[] index = new Integer[2];
                    index[0] = list.indexOf(key);
                    index[1] = list.lastIndexOf(key);
                    indexList.add(index);
                }
            }
            return indexList;
        }
    
    }
    

    2.自定义XWPFDocument类

    package com.management.util;
    
    import org.apache.xmlbeans.XmlException;
    import org.apache.xmlbeans.XmlToken;
    import org.apache.poi.openxml4j.opc.OPCPackage;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    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 java.io.IOException;
    import java.io.InputStream;
    
    /**
     * Created by wfg 2020-08-12.
     * 自定义 XWPFDocument,并重写 createPicture()的方法
     */
    public class CustomXWPFDocument extends XWPFDocument{
        public CustomXWPFDocument(InputStream in) throws IOException {
            super(in);
        }
    
        public CustomXWPFDocument() {
            super();
        }
    
        public CustomXWPFDocument(OPCPackage pkg) throws IOException {
            super(pkg);
        }
    
        /**
         * @param id
         * @param width 宽
         * @param height 高
         * @param paragraph  段落
         */
        public void createPicture(String blipId, int id, int width, int height, XWPFParagraph paragraph) {
            final int EMU = 9525;
            width *= EMU;
            height *= EMU;
            CTInline inline = paragraph.createRun().getCTR().addNewDrawing().addNewInline();
    
            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);
    
            CTPositiveSize2D extent = inline.addNewExtent();
            extent.setCx(width);
            extent.setCy(height);
    
            CTNonVisualDrawingProps docPr = inline.addNewDocPr();
            docPr.setId(id);
            docPr.setName("图片" + id);
            docPr.setDescr("头像");
        }
    }
    

    3.创建测试类

    注意使用的word模板,要有一个表头和一行空数据,要不运行会报错空指针,找不到有效行,运行下面的类后,即可看到效果

    package com.management.web;
    
    import com.management.util.CustomXWPFDocument;
    import com.management.util.ExportWordUtil;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class TestWord {
        public static void main(String[] args) throws Exception {
            //需要进行文本替换的信息
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("${date}", "(2020年08月12日)");
            data.put("${name}", "测试一下");
           
            //图片,如果是多个图片,就新建多个map
           /* Map<String,Object> picture1 = new HashMap<String, Object>();
            picture1.put("width", 100);
            picture1.put("height", 150);
            picture1.put("type", "jpg");
            picture1.put("content", ExportWordUtil.inputStream2ByteArray(new FileInputStream("D:/timg.jpg"), true));
            data.put("${picture1}",picture1);
    */
            //需要进行动态生成的信息
            List<Object> mapList = new ArrayList<Object>();
    
            //第一个动态生成的数据列表
            List<String[]> list01 = new ArrayList<String[]>();
            list01.add(new String[]{"A","11111111111","22","22","22","22","22"});
            list01.add(new String[]{"A","22222222222","33","22","22","22","22"});
            list01.add(new String[]{"B","33333333333","44","22","22","22","22"});
            list01.add(new String[]{"B","44444444444","55","22","22","22","22"});
            list01.add(new String[]{"B","33333333333","44","22","22","22","22"});
            list01.add(new String[]{"C","44444444444","55","22","22","22","22"});
            list01.add(new String[]{"C","33333333333","44","22","22","22","22"});
            list01.add(new String[]{"C","44444444444","55","22","22","22","22"});
            list01.add(new String[]{"C","44444444444","55","22","22","22","22"});
            //第二个动态生成的数据列表
            List<String[]> list02 = new ArrayList<String[]>();
            list02.add(new String[]{"A","11111111111","22","22","22","22","22"});
            list02.add(new String[]{"d","22222222222","33","22","22","22","22"});
            list02.add(new String[]{"B","33333333333","44","22","22","22","22"});
            list02.add(new String[]{"C","44444444444","55","22","22","22","22"});
    
            mapList.add(list01);
            //mapList.add(list02);
    
            //需要动态改变表格的位置;第一个表格的位置为0,1
            int[] placeList = {0,1};
    
            CustomXWPFDocument doc = ExportWordUtil.changWord("D:/word.docx",data,mapList,placeList);
            FileOutputStream fopts = new FileOutputStream("D:/合并表格.docx");
            doc.write(fopts);
            fopts.close();
        }
    
    
    }
    
    
    展开全文
  • java利用poi模板导出word文件

    千次阅读 2020-05-06 12:11:27
    doc文件的读取,需要导入poi-scratchpad包: docx文件读取,需要导入poi-ooxml包: 一、引入pom <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</...
  • tagValue, tagName : ', img, tagValue, tagName) reject(e) } }) } //角度筛选器 (可以在word中进行一些复杂的 运算)如果加入角度解析器模板报错一般是特殊字符导致比如下面的%此处替换不会影响导出 let ...
  • poi导出word模板

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

    千次阅读 2016-10-28 17:00:42
    本文章来自【知识林】导出Word文件其实与Springboot没有多大关系,这都是Apache子项目POI的功劳。下面简单介绍一下在Springboot项目中如何使用POI导出Word文件。 pom.xml文件 <groupId>org.springframework.boot ...
  • poi 导出word 表格文件

    千次阅读 2017-02-15 18:56:17
    poi导出word文件,其实很简单,下面我为大家写了一个样例//创建一个doc对象 XWPFDocument xdoc = new XWPFDocument(); //创建段落对象 XWPFParagraph p = xdoc.createParagraph(); //通过段落对象,创建字体对象。...
  • 学习分享:POI-TL 导出Word复杂表格合并分享

    千次阅读 多人点赞 2021-01-11 15:39:35
    学习分享:POI-TL 导出Word合并表格 文章目录学习分享:POI-TL 导出Word合并表格关于POI-TL 导出Word的一些使用一、前期准备?二、代码演示1.数据结构2.代码示例2.1 写入表头表体的数据2.2 设置合并规则2.3 输出结果...
  • 我现在做的项目要用到导出文件的功能,然后就去学了Apache POI通过模板文件生成word文档的功能。 我写的demo在main方法和web接口下都能正常生成生成word文档;但是一移植到公司的项目上就报错了,controller和...
  • 使用poi导出word

    千次阅读 2016-11-12 15:51:47
    项目需求要把页面上的分析结果导出word文档,实现的办法是POI。查了一下网上很多方式都采用FreeMark,自己认为比较麻烦,所以还是采取了POI导出。之前的框架是SSH的,现在换成了spring MVC,这次也把导出代码整理...
  • 需求:根据一个word模板,在程序中替换模板中的参数,然后根据这个模板导出word文件。 引入POI对word操作的依赖: <dependency> <groupId>org.apache.poi</groupId> <artifactId>...
  • Java使用POI方式导出office Word文档

    万次阅读 2017-05-14 21:47:32
    1.1 实例1在使用POIword doc文件的时候我们必须要先有一个doc文件才行,因为我们在写doc文件的时候是通过HWPFDocument来写的,而HWPFDocument是要依附于一个doc文件的。所以通常的做法是我们先在硬盘上准备好一个...
  • 暑期在杭州实习了两个月,主要是使用vue+SpringMVC进行...在网上搜索了许多方法,了解到要导出word文件,其实办法由很多,如jacob,java2word,FreeMarker,Apatch POI等等。 本文采用的是Apatch POI中的一系列API,它...
  • java工具类POI导出word

    2017-12-09 16:40:00
    1、新建一个word,里面填写内容,如: 2、导出wordjava类 ... * POI导出word测试 * @throws Exception */ @RequestMapping(value="exportApplyForm") public void exportApplyForm(HttpServletRespon...
  • POI导出Word表格

    千次阅读 2018-08-24 15:13:55
    网上很有多拿到word模板然后对其赋值的例子我就不多说了 我这边就只记录创建document table public InputStream exportWordContainTable(){ try { ByteArrayOutputStream os = new ByteArrayOutputStream(); ...
  • 模版word文件 生成的word文件 代码 //自己使用做下简单的封装即可 public static void main(String[] args) { //示例数据 Map<String, Object> map = new HashMap<>(); map.put("name", "李四1");...
  • ![图片说明](https://img-ask.csdn.net/upload/201607/23/1469241418_405188.png)
  • Apache poi导出word和Excle

    2016-08-09 15:26:33
    最近的训练中,遇到需要导出excel和word,通过网上找资料还是完成了的,此处帖子个人的总结。 excel和word导出需要的包: 先说excel: // 创建一个webbook,对应一个Excel文件  HSSFWorkbook wb = new ...
  • , 【项目实战】Java POIWord导出经典案例一 Java POI 读取word文件 POI-对于WORD的操作(一) 转载于:https://www.cnblogs.com/whatlonelytear/p/7680081.html
  • /** *写入图片 *@paramdocument *@parampicName *@paramwidth *@paramheight *@paramalignment */ privatevoidWriteImage(CustomXWPFDocumentdocument,StringpicName,i...
  • "\"临时文件已写入成功,地址:" + temPath + "\"" ); } catch ( FileNotFoundException e ) { // TODO Auto-generated catch block e . printStackTrace (); } catch ( IOException ...
  • 导出word文档的过程中因为文档信息展示需要,要在指定位置插入图片,遇到的一系列问题整理: POI框架在处理Excel文档方面功能的确很强大,但是在处理word文档方面就略显劣势,使用poi在文档中插入图片时打开文档...
  • 使用POI 导出word模板文件

    千次阅读 热门讨论 2019-03-21 11:29:32
    maven依赖 <dependency> ...org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.16</version> </dependency> 自定义XWPFDocu...
  • poi用于写入导出excel,word等文件

    千次阅读 2013-11-22 14:32:37
    http://poi.apache.org/spreadsheet/examples.html 这里有些例子,点里面链接可以看到代码。 或者去这里http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/ 这些都是...
  • poi导出word2003 动态数据 生成word能再次poi导入

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,555
精华内容 622
关键字:

poi写入导出word