这是poi利用模板生成word文档的例子

public XWPFDocument doc = null;
    public XWPFDocument outputDoc = null;
    public String outputFilePath = null;
    public String tempFilePath = null;
    public boolean isFirst = false;

    /** 
     * word整体样式 
     */  
    public static CTStyles wordStyles = null;

    public BugReport(String outputFilePath, String modelPath, String tempFilePath) {
        this.outputFilePath = outputFilePath;
        this.tempFilePath = tempFilePath;
        if(doc == null){
            try {
                //获取模板操作对象
                doc = new XWPFDocument(POIXMLDocument.openPackage(modelPath));
                //获取模板文档的整体格式对象
                wordStyles = doc.getStyle();
                //新建文档操作对象
                outputDoc = new XWPFDocument();
                // 获取新建文档对象的样式  
                XWPFStyles newStyles = outputDoc.createStyles();  
                // 关键行// 修改设置文档样式为静态块中读取到的样式  
                newStyles.setStyles(wordStyles);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println("创建文档出错!");
                PrintLog.writeLog("创建文档出错!\n");
                Utils.deleteFile(outputFilePath);
            } catch (XmlException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

    /**
     * 向文档中插入模板中的表格
     * @param pos
     * @return
     */
    public XWPFTable insertTable() {
        // TODO Auto-generated method stub
        XWPFTable table = null;
        Iterator<XWPFTable> itTable = doc.getTablesIterator();
        while(itTable.hasNext()){
            table = (XWPFTable)itTable.next();
            break;
        }
        XWPFTable table_temp = table;
        List<XWPFTableRow> rows = table_temp.getRows();
        XWPFTable createTable = outputDoc.createTable();
        for (int i = 0; i < rows.size(); i++) {
            createTable.addRow(rows.get(i));
        }
        createTable.removeRow(0);
        return createTable;
    }

    /**
     * 向文档中插入模板中的表格
     * 遍历模板表格的每个单元格创建表格,但是合并单元格还有一点小问题
     * 这种方法容易控制表格的格式
     * @return
     */
    public XWPFTable insertTable1() {
        // TODO Auto-generated method stub
        XWPFTable table = null;
        Iterator<XWPFTable> itTable = doc.getTablesIterator();
        while(itTable.hasNext()){
            table = (XWPFTable)itTable.next();
            break;
        }
        List<XWPFTableRow> rows = table.getRows();

        int maxCol = 0;
        for (int i = 0; i < rows.size(); i++) {
            List<XWPFTableCell> tableCells = rows.get(i).getTableCells();
            if(maxCol < tableCells.size()){
                maxCol = tableCells.size();
            }
            for (int j = 0; j < tableCells.size(); j++) {

            }
        }

        XWPFTable createTable = outputDoc.createTable(rows.size(), maxCol);
        XWPFUtil.setTableWidth(createTable, table.getCTTbl().getTblPr().getTblW().getW().toString());
        //由于第7行单元格合并后无法赋值,这里没有合并第7行
        XWPFUtil.mergeCellsHorizontal(createTable, 0, 1, 4);
        XWPFUtil.mergeCellsHorizontal(createTable, 4, 0, 4);
        XWPFUtil.mergeCellsHorizontal(createTable, 5, 0, 4);

//      XWPFUtil.mergeCellsHorizontal(createTable, 6, 0, 2);
//      XWPFUtil.mergeCellsHorizontal(createTable, 6, 2, 4);
        //循环查找模板表格中的每一行
        for (int i = 0; i < rows.size(); i++) {
            //获取当前新建表格的指定行
            XWPFTableRow row = createTable.getRow(i);
            row.setHeight(rows.get(i).getHeight());
            //获取模板当前行的单元格列表
            List<XWPFTableCell> tableCells = rows.get(i).getTableCells();
            for (int j = 0; j < tableCells.size(); j++) {
                XWPFTableCell cell = null;
                //获取当前操作单元格
                if(i == 6 && j == 0){
                    cell = row.getCell(0);
                }else if(i == 6 && j == 1){
                    cell = row.getCell(2);
                }else{
                    cell = row.getCell(j);
                }
                cell = row.getCell(j);
                //获取模板当前单元格
                XWPFTableCell tableCell = tableCells.get(j);
                //获取模板单元格中的段落列表
                List<XWPFParagraph> paragraphs = tableCell.getParagraphs();

                //将模板单元格格式赋给当前新建表格的单元格格式
                CTTc ctTc = cell.getCTTc();
                CTTcPr addNewTcPr = ctTc.addNewTcPr();
                CTTblWidth addNewTcW = addNewTcPr.addNewTcW();
                addNewTcW.setW(tableCell.getCTTc().getTcPr().getTcW().getW());
                addNewTcW.setType(STTblWidth.DXA);
                cell.setVerticalAlignment(tableCell.getVerticalAlignment());

                //循环查找模板指定单元格的段落列表
                for (int p_i = 0; p_i < paragraphs.size(); p_i++) {
                    //获取段落中的run列表
                    List<XWPFRun> runs = paragraphs.get(p_i).getRuns();
                    //获取当前操作段落
                    XWPFParagraph xwpfParagraph = null;
                    if(p_i > 0){
                        xwpfParagraph = cell.addParagraph();
                    }else{
                        xwpfParagraph = cell.getParagraphArray(0);
                    }
                    //获取模板段落格式赋给新建单元格的段落
                    xwpfParagraph.setIndentationLeft(paragraphs.get(p_i).getIndentationLeft());
                    xwpfParagraph.setFirstLineIndent(paragraphs.get(p_i).getFirstLineIndent());
                    xwpfParagraph.setAlignment(paragraphs.get(p_i).getAlignment());
                    xwpfParagraph.setVerticalAlignment(paragraphs.get(p_i).getVerticalAlignment());
                    //循环查找指定单元格的指定段落的run列表
                    for (int r_i = 0; r_i < runs.size(); r_i++) {
                        XWPFRun createRun = xwpfParagraph.createRun();
//                      CTRPr rPr = runs.get(r_i).getCTR().getRPr();
//                      CTFonts fonts = rPr.getRFonts();
                        if(paragraphs.get(p_i).getStyle() != null){
                            xwpfParagraph.setStyle(paragraphs.get(p_i).getStyle());
                        }else if(runs.get(r_i).getFontSize() != -1){
                            XWPFUtil.setXWPFRunFont(createRun, runs.get(r_i).getFontSize() * 2 + "", runs.get(r_i).getFontFamily());
                        }else{
                            XWPFUtil.setXWPFRunFont(createRun, Constant.FONT_21, runs.get(r_i).getFontFamily());
                        }
                        createRun.setBold(runs.get(r_i).isBold());
                        createRun.setText(runs.get(r_i).text());
                    }
                }
            }

        }
        XWPFUtil.mergeCellsHorizontal(createTable, 6, 0, 2);
        XWPFUtil.mergeCellsHorizontal(createTable, 6, 2, 4);
        return createTable;
    }

    /**
     * 向文档中插入模板中的段落
     * @return
     */
    public Iterator<XWPFParagraph> insertParagraph(){
        //替换段落中的指定文字
        Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
//      System.out.println("###");
        //不是第一次进入则插入分页符
        if(isFirst){
            XWPFParagraph para = outputDoc.createParagraph();
            XWPFRun createRun = para.createRun();
            createRun.addBreak(BreakType.PAGE);
        }else{
            //第一次进入
            isFirst = !isFirst;
        }

        //迭代搜索模板中的paragraph
        while(iterator.hasNext()){
            XWPFParagraph xwpfParagraph = iterator.next();
            XWPFParagraph paragraph = null;

            List<XWPFRun> next = xwpfParagraph.getRuns();
            for (int i = 0; i < next.size(); i++) {
                //为空的paragraph不做处理
                if(!"".equals(next.get(i).toString()) && !"\n".equals(next.get(i).toString())){
                    if(paragraph == null){
                        paragraph = outputDoc.createParagraph();
                        paragraph.setAlignment(xwpfParagraph.getAlignment());
                        paragraph.setIndentationRight(xwpfParagraph.getIndentationLeft());
                        paragraph.setIndentationFirstLine(xwpfParagraph.getFirstLineIndent());
                    }
                    XWPFRun newRun = paragraph.insertNewRun(0);
                    newRun.setBold(next.get(i).isBold());
                    newRun.setFontFamily(next.get(i).getFontFamily());
                    newRun.setFontSize(next.get(i).getFontSize());
                    newRun.setText(next.get(i).text());
                }

            }
        }
        return iterator;

    }

    /**
     * 将数据插入表格中,保存到指定输出路径中
     * @param listInfo 需要插入表格的数据
     */
    public void insertDataToTable(List<HashMap<String, Object>> listInfo){
        System.out.println("insertDataToTable");
        PrintLog.writeLog("insertDataToTable\n");
        XWPFDocument outputDoc = null;

        try {
            outputDoc = new XWPFDocument(POIXMLDocument.openPackage(tempFilePath));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        List<XWPFTable> tables = outputDoc.getTables();
        System.out.println("listInfo.size=" + listInfo.size());

        for (int i = 0; i < tables.size(); i++) {
            System.out.println("开始替换");
            PrintLog.writeLog("开始替换\n");
            //替换表格中的指定文字
            List<XWPFParagraph> paras;
            int rcount = tables.get(i).getNumberOfRows();

            for (int j = 0; j < rcount; j++) {
                System.out.println("rcount=" + rcount);
                PrintLog.writeLog("rcount=" + rcount + "\n");
                XWPFTableRow row = tables.get(i).getRow(j);
                List<XWPFTableCell> cells = row.getTableCells();

                for (XWPFTableCell cell : cells) {
                    paras = cell.getParagraphs();

                    for (XWPFParagraph para : paras) {
                        List<XWPFRun> runs = para.getRuns();

                        for (XWPFRun xwpfRun : runs) {
                            xwpfRun.setTextPosition(10);
                        }

                        replaceInPara(para, listInfo.get(i));
                    }

                }

            }

            System.out.println("结束替换");
            PrintLog.writeLog("结束替换\n");
        }
        closeWriteInDocument(outputDoc);
    }



    /**
     * 这是生成多个文档使用的方法
     * 将数据插入表格中,保存到指定输出路径中
     * @param listInfo 需要插入表格的数据
     * @param count 生成的文档个数
     */
    public void insertDataToTable(List<HashMap<String, Object>> listInfo, int count){
        System.out.println("insertDataToTable");
        PrintLog.writeLog("insertDataToTable\n");
        XWPFDocument outputDoc = null;
        try {
            System.out.println("tempFilePath=" + tempFilePath);
            PrintLog.writeLog("tempFilePath=" + tempFilePath  + "\n");
            outputDoc = new XWPFDocument(POIXMLDocument.openPackage(tempFilePath));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Utils.deleteFile(outputFilePath, tempFilePath);
        }
        List<XWPFTable> tables = outputDoc.getTables();
        System.out.println("listInfo.size=" + listInfo.size());
        for (int i = 0; i < tables.size(); i++) {
            System.out.println("开始替换");
            PrintLog.writeLog("开始替换\n");
            //替换表格中的指定文字
            List<XWPFParagraph> paras;
            int rcount = tables.get(i).getNumberOfRows();
            for (int j = 0; j < rcount; j++) {
                System.out.println("rcount=" + rcount);
                PrintLog.writeLog("rcount=" + rcount + "\n");
                XWPFTableRow row = tables.get(i).getRow(j);
                List<XWPFTableCell> cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    paras = cell.getParagraphs();
                    for (XWPFParagraph para : paras) {
                        List<XWPFRun> runs = para.getRuns();
                        for (XWPFRun xwpfRun : runs) {
                            xwpfRun.setTextPosition(10);
                        }
                        replaceInPara(para, listInfo.get(Constant.TABLE_COUNT * (count) + i));
                    }
                }
            }
            System.out.println("结束替换");
            PrintLog.writeLog("结束替换\n");
        }
        closeWriteInDocument(outputDoc);
    }





    /**
     * 写出文档内容并关闭输出流
     * @param outputDoc 指定操作文档对象
     */
    public void closeWriteInDocument(XWPFDocument outputDoc){
        try {
            System.out.println("closeWriteInDocument-->outputDoc");
            PrintLog.writeLog("closeWriteInDocument-->outputDoc\n");
            OutputStream os = new FileOutputStream(outputFilePath);
            outputDoc.write(os);
            os.close();
            outputDoc.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println("文档写出出错!");
            PrintLog.writeLog("文档写出出错!\n");
            Utils.deleteFile(outputFilePath, tempFilePath);
        }
    }



    /**
     * 将模板中的内容插入临时文档中,形成模板列表
     * @param modelPath
     * @param pos
     */
    public void insertTableToDocument(){
        System.out.println("insertTableToDocument");
        PrintLog.writeLog("insertTableToDocument\n");
        try {
            //插入段落
            System.out.println("插入段落");
            PrintLog.writeLog("插入段落\n");
            Iterator<XWPFParagraph> iterator = insertParagraph();

            //插入表格
            System.out.println("插入表格");
            PrintLog.writeLog("插入表格\n");
            XWPFTable table = insertTable();

//          XWPFTable table = tables.get(pos);


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Utils.deleteFile(outputFilePath, tempFilePath);
        }
    }



    /**
     * 写出文档内容并关闭输出流
     * 默认关闭临时文档对象
     */
    public void closeWriteInDocument(){
        try {

            System.out.println("closeWriteInDocument");
            PrintLog.writeLog("closeWriteInDocument\n");
            OutputStream os = new FileOutputStream(tempFilePath);
            outputDoc.write(os);
            os.close();
            outputDoc.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println("文档写出出错!");
            Utils.deleteFile(outputFilePath, tempFilePath);
        }
    }
/**
     * 在段落中替换指定标签的数据
     * @param para
     * @param map
     */
    public void replaceInPara(XWPFParagraph para, Map<String, Object> map){
        List<XWPFRun> runs;
        Matcher matcher;
        if((matcher = Utils.matcher(para.getParagraphText())).find()){
            System.out.println("para=" + para.getParagraphText());
            PrintLog.writeLog("para=" + para.getParagraphText() + "\n");
            runs = para.getRuns();

            int size = runs.size();
            //获取模板样式,将其赋给新文档
            for (int i = 0; i < size; i++) {
                XWPFRun run = runs.get(i);
                boolean isBold = run.isBold();
                String fontFamily = run.getFontFamily();
                String runText = run.toString();
                String group = matcher.group(1);
                Object replacement = map.get(group);
                para.removeRun(i);
                XWPFRun newRun = para.insertNewRun(i);
                newRun.setFontFamily(fontFamily);
                newRun.setBold(isBold);
                if(runText.equals(group)){
                    if(Constant.CONST_BOOKMARK9.equals(group)){
                        String[] split = ((String)replacement).split("@");
                        for (int j = 0; j < split.length; j++) {
                            newRun.setText(split[j]);
                            if(j + 1 == split.length){
                                break;
                            }
                            newRun.addBreak();
                        }
                    }else if(Constant.CONST_BOOKMARK8.equals(group)){
                        insertTextAndPic(replacement, para);
                    }else if(Constant.CONST_BOOKMARK4.equals(group) || Constant.CONST_BOOKMARK5.equals(group)){
                            newRun.setBold(true);
                            newRun.setText((String)replacement);
                    }else{
                            newRun.setText((String)replacement);
                    }
                }
            }
        }
    }

    /**
     * 插入实例内容
     * @param replacement
     * @param para
     */
    public void insertTextAndPic(Object replacement, XWPFParagraph para){
        System.out.println("saveDataToWord");
        PrintLog.writeLog("saveDataToWord\n");
        try {
            Cases cases = (Cases) replacement;
            String imgPath = "";
            String textInfo = "";
            para.setIndentationLeft(400);
            para.setIndentationHanging(2);  
            para.setAlignment(ParagraphAlignment.NUM_TAB);
//          XWPFRun xwpfRun = para.getRuns().get(0);

//          para.setWordWrapped(true);
            for (int i = 0; i < cases.getDescribing().size(); i++) {
                textInfo = Constant.CONST5 + (i + 1);

                XWPFRun newRun = para.createRun();
                newRun.setFontFamily(Constant.FONT_SONGTI);
                newRun.setBold(true);
                newRun.setColor(Constant.COLOR_BLUE);
                newRun.setText(textInfo);
                newRun.addBreak();
                textInfo = cases.getDescribing().get(i);
                XWPFRun newRun1 = para.createRun();
                newRun1.setFontFamily(Constant.FONT_SONGTI);
                newRun1.setBold(false);
                newRun1.setColor(Constant.COLOR_BLACK);
                newRun1.setText(textInfo);
                newRun1.addBreak();
                imgPath = cases.getImgPath().get(i);
                System.out.println("path="+imgPath);
                File imgFile = new File(imgPath);
                if(imgFile.exists()){
                    InputStream is = new FileInputStream(imgFile);
                    XWPFRun newRun2 = para.createRun();
                    newRun2.addPicture(is, Utils.getPicType(Utils.getSuffix(imgPath)), imgPath, Units.toEMU(300), Units.toEMU(200));
                    newRun2.addBreak();
                }

//                  newRun.addBreak(BreakType.PAGE);
                }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Utils.deleteFile(outputFilePath, tempFilePath);
        }
    }
public class XWPFUtil {

    /**
     * 设置XWPFRun的字体
     * @param run
     * @param fontSize 字体大小
     * @param fontFamily 字体风格
     */
    public static void setXWPFRunFont(XWPFRun xwpfRun, String fontSize, String fontFamily){
        CTRPr pRpr = null;
        if(xwpfRun.getCTR() != null){
            pRpr = xwpfRun.getCTR().getRPr();
            if(pRpr == null){
                pRpr = xwpfRun.getCTR().addNewRPr();
            }
        }
        CTHpsMeasure sz = pRpr.isSetSz() ? pRpr.getSz() : pRpr.addNewSz();
        sz.setVal(new BigInteger(fontSize));
        CTFonts fonts = pRpr.isSetRFonts() ? pRpr.getRFonts() : pRpr.addNewRFonts();
        fonts.setAscii(fontFamily);
        fonts.setEastAsia(fontFamily);
        fonts.setHAnsi(fontFamily);
    }

    /**
     * 设置表格宽度
     * @param table
     * @param width
     */
    public static void setTableWidth(XWPFTable table, String width){
        CTTbl ctTbl = table.getCTTbl();
        CTTblPr tbPr = ctTbl.getTblPr() == null ? ctTbl.addNewTblPr() : ctTbl.getTblPr();
        CTTblWidth tblWidth = tbPr.isSetTblW() ? tbPr.getTblW() : tbPr.addNewTblW();
        CTJc ctJc = tbPr.addNewJc();
        ctJc.setVal(STJc.Enum.forString("center"));
        tblWidth.setW(new BigInteger(width));
        tblWidth.setType(STTblWidth.DXA);
    }

    /**
     * 合并列
     * @param table
     * @param row 合并列的行号(从0开始)
     * @param fromCell 开始合并的列的列号
     * @param toCell 结束合并的列的列号
     */
    public static void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell){
        for (int cellIndex = fromCell; cellIndex < toCell; cellIndex++) {
            XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
            if(cellIndex == fromCell){
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            }else{
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }
}