1. 程式人生 > >使用POI匯出Word(含表格)的實現方式及操作Word的工具類

使用POI匯出Word(含表格)的實現方式及操作Word的工具類

轉載請註明出處:https://www.cnblogs.com/sun-flower1314/p/10128796.html 

本篇是關於利用Apache 的POI匯出Word的實現步驟。採用XWPFDocument匯出Word,結構和樣式完全由程式碼控制,操作起來還是非常的不太方便,只能夠建立簡單的word,不能設定樣式,功能太少。但在這裡還是實現一下,畢竟做過。

首先宣告一些基本概念:

XWPFDocument代表一個docx文件,其可以用來讀docx文件,也可以用來寫docx文件
XWPFParagraph代表文件、表格、標題等種的段落,由多個XWPFRun組成
XWPFRun代表具有同樣風格的一段文字
XWPFTable

代表一個表格
XWPFTableRow代表表格的一行
XWPFTableCell代表表格的一個單元格
XWPFChar 表示.docx檔案中的圖表
XWPFHyperlink 表示超連結
XWPFPicture 代表圖片

注意:直接呼叫XWPFRun的setText()方法設定文字時,在底層會重新建立一個XWPFRun。

先看效果圖:(完全是由程式碼匯出)

 

1.用到的包:(雖然只有兩個,但是會依賴其他jar包進來)

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.17</version>
    </dependency>

 

這是依賴包:

2..粗魯一點了,直接上程式碼:

package cn.hxc.myWorld.myWorld;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
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.STJc; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc; import cn.hxc.myWorld.util.XWPFHelper; import cn.hxc.myWorld.util.XWPFHelperTable; /** * @Description 匯出word文件 * @Author Huangxiaocong * 2018年12月1日 下午12:12:15 */ public class ExportWord { private XWPFHelperTable xwpfHelperTable = null; private XWPFHelper xwpfHelper = null; public ExportWord() { xwpfHelperTable = new XWPFHelperTable(); xwpfHelper = new XWPFHelper(); } /** * 建立好文件的基本 標題,表格 段落等部分 * @return * @Author Huangxiaocong 2018年12月16日 */ public XWPFDocument createXWPFDocument() { XWPFDocument doc = new XWPFDocument(); createTitleParagraph(doc); createTableParagraph(doc, 10, 6); return doc; } /** * 建立表格的標題樣式 * @param document * @Author Huangxiaocong 2018年12月16日 下午5:28:38 */ public void createTitleParagraph(XWPFDocument document) { XWPFParagraph titleParagraph = document.createParagraph(); //新建一個標題段落物件(就是一段文字) titleParagraph.setAlignment(ParagraphAlignment.CENTER);//樣式居中 XWPFRun titleFun = titleParagraph.createRun(); //建立文字物件 // titleFun.setText(titleName); //設定標題的名字 titleFun.setBold(true); //加粗 titleFun.setColor("000000");//設定顏色 titleFun.setFontSize(25); //字型大小 // titleFun.setFontFamily("");//設定字型 //... titleFun.addBreak(); //換行 } /** * 設定表格 * @param document * @param rows * @param cols * @Author Huangxiaocong 2018年12月16日 */ public void createTableParagraph(XWPFDocument document, int rows, int cols) { // xwpfHelperTable.createTable(xdoc, rowSize, cellSize, isSetColWidth, colWidths) XWPFTable infoTable = document.createTable(rows, cols); xwpfHelperTable.setTableWidthAndHAlign(infoTable, "9072", STJc.CENTER); //合併表格 xwpfHelperTable.mergeCellsHorizontal(infoTable, 1, 1, 5); xwpfHelperTable.mergeCellsVertically(infoTable, 0, 3, 6); for(int col = 3; col < 7; col++) { xwpfHelperTable.mergeCellsHorizontal(infoTable, col, 1, 5); } //設定表格樣式 List<XWPFTableRow> rowList = infoTable.getRows(); for(int i = 0; i < rowList.size(); i++) { XWPFTableRow infoTableRow = rowList.get(i); List<XWPFTableCell> cellList = infoTableRow.getTableCells(); for(int j = 0; j < cellList.size(); j++) { XWPFParagraph cellParagraph = cellList.get(j).getParagraphArray(0); cellParagraph.setAlignment(ParagraphAlignment.CENTER); XWPFRun cellParagraphRun = cellParagraph.createRun(); cellParagraphRun.setFontSize(12); if(i % 2 != 0) { cellParagraphRun.setBold(true); } } } xwpfHelperTable.setTableHeight(infoTable, 560, STVerticalJc.CENTER); } /** * 往表格中填充資料 * @param dataList * @param document * @throws IOException * @Author Huangxiaocong 2018年12月16日 */ @SuppressWarnings("unchecked") public void exportCheckWord(Map<String, Object> dataList, XWPFDocument document, String savePath) throws IOException { XWPFParagraph paragraph = document.getParagraphArray(0); XWPFRun titleFun = paragraph.getRuns().get(0); titleFun.setText(String.valueOf(dataList.get("TITLE"))); List<List<Object>> tableData = (List<List<Object>>) dataList.get("TABLEDATA"); XWPFTable table = document.getTableArray(0); fillTableData(table, tableData); xwpfHelper.saveDocument(document, savePath); } /** * 往表格中填充資料 * @param table * @param tableData * @Author Huangxiaocong 2018年12月16日 */ public void fillTableData(XWPFTable table, List<List<Object>> tableData) { List<XWPFTableRow> rowList = table.getRows(); for(int i = 0; i < tableData.size(); i++) { List<Object> list = tableData.get(i); List<XWPFTableCell> cellList = rowList.get(i).getTableCells(); for(int j = 0; j < list.size(); j++) { XWPFParagraph cellParagraph = cellList.get(j).getParagraphArray(0); XWPFRun cellParagraphRun = cellParagraph.getRuns().get(0); cellParagraphRun.setText(String.valueOf(list.get(j))); } } } }

 下面是用到的工具類:

package cn.hxc.myWorld.util;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.TextAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFPicture;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.poi.xwpf.usermodel.XWPFRelation;
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.CTFonts;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule;

import cn.hxc.myWorld.domain.ParagraphStyle;
import cn.hxc.myWorld.domain.TextStyle;

/**
 * @Description 設定docx文件的樣式及一些操作  
 * @Author  Huangxiaocong
 * 2018年12月1日  下午12:18:41
 * 基本概念說明:XWPFDocument代表一個docx文件,其可以用來讀docx文件,也可以用來寫docx文件
 *     XWPFParagraph代表文件、表格、標題等種的段落,由多個XWPFRun組成
 *     XWPFRun代表具有同樣風格的一段文字
 *  XWPFTable代表一個表格
 *  XWPFTableRow代表表格的一行
 *  XWPFTableCell代表表格的一個單元格    
 *  XWPFChar 表示.docx檔案中的圖表
 *  XWPFHyperlink 表示超連結
 *  XWPFPicture  代表圖片
 *  
 *  注意:直接呼叫XWPFRun的setText()方法設定文字時,在底層會重新建立一個XWPFRun。
 */
public class XWPFHelper {
    private static Logger logger = Logger.getLogger(XWPFHelper.class.toString());
    
    /**
     * 建立一個word物件
     * @return
     * @Author Huangxiaocong 2018年12月1日 上午11:56:35
     */
    public XWPFDocument createDocument() {
        XWPFDocument document = new XWPFDocument();
        return document;
    }
    /**
     * 開啟word文件
     * @param path 文件所在路徑
     * @return
     * @throws IOException
     * @Author Huangxiaocong 2018年12月1日 下午12:30:07
     */
    public XWPFDocument openDoc(String path) throws IOException {
        InputStream is = new FileInputStream(path);
        return new XWPFDocument(is);
    }
    /**
     * 儲存word文件
     * @param document 文件物件
     * @param savePath    儲存路徑
     * @throws IOException
     * @Author Huangxiaocong 2018年12月1日 下午12:32:37
     */
    public void saveDocument(XWPFDocument document, String savePath) throws IOException {
        OutputStream os = new FileOutputStream(savePath);
        document.write(os);
        os.close();
    }
    /**
     * 設定段落文字樣式  設定超連結及樣式
     * @param paragraph
     * @param textStyle
     * @param url
     * @Author Huangxiaocong 2018年12月1日 下午3:56:32
     */
    public void addParagraphTextHyperlink(XWPFParagraph paragraph, TextStyle textStyle) {
        String id = paragraph.getDocument().getPackagePart().
            addExternalRelationship(textStyle.getUrl(),
                XWPFRelation.HYPERLINK.getRelation()).getId();
        //追加連結並將其繫結到關係中
        CTHyperlink cLink = paragraph.getCTP().addNewHyperlink();
        cLink.setId(id);
        //建立連結文字
        CTText ctText = CTText.Factory.newInstance();
        ctText.setStringValue(textStyle.getText());
        CTR ctr = CTR.Factory.newInstance();
        CTRPr rpr = ctr.addNewRPr();
        //以下設定各種樣式 詳情看TextStyle類
        if(textStyle.getFontFamily() != "" && textStyle.getFontFamily() != null     ) {
            CTFonts fonts = rpr.isSetRFonts() ? rpr.getRFonts() : rpr.addNewRFonts();
            fonts.setAscii(textStyle.getFontFamily());
            //...
        }
        //設定字型大小
    }
    /**
     * 設定段落的基本樣式  設定段落間距資訊, 一行 = 100    一磅=20 
     * @param paragraph
     * @param paragStyle
     * @Author Huangxiaocong 2018年12月1日 下午4:27:17
     */
    public void setParagraphSpacingInfo(XWPFParagraph paragraph, ParagraphStyle paragStyle, STLineSpacingRule.Enum lineValue) {
        CTPPr pPPr = getParagraphCTPPr(paragraph);
        CTSpacing pSpacing = pPPr.getSpacing() != null ? pPPr.getSpacing() : pPPr.addNewSpacing();
        if(paragStyle.isSpace()) {
            //段前磅數
            if(paragStyle.getBefore() != null) {
                pSpacing.setBefore(new BigInteger(paragStyle.getBefore()));
            }
            //段後磅數
            if(paragStyle.getAfter() != null) {
                pSpacing.setAfter(new BigInteger(paragStyle.getAfter()));
            }
            //依次設定段前行數、段後行數
            //...
        }
        //間距
        if(paragStyle.isLine()) {
            if(paragStyle.getLine() != null) {
                pSpacing.setLine(new BigInteger(paragStyle.getLine()));
            }
            if(lineValue != null) {
                pSpacing.setLineRule(lineValue);    //
            }
        }
    }
    /**
 * 設定段落縮排資訊  1釐米 約等於 567
     * @param paragraph
     * @param paragStyle
     * @Author Huangxiaocong 2018年12月1日 下午7:59:35
     */
    public void setParagraphIndInfo(XWPFParagraph paragraph, ParagraphStyle paragStyle) {
        CTPPr pPPr = getParagraphCTPPr(paragraph);
        CTInd pInd = pPPr.getInd() != null ? pPPr.getInd() : pPPr.addNewInd();
        if(paragStyle.getFirstLine() != null) {
            pInd.setFirstLine(new BigInteger(paragStyle.getFirstLine()));
        }
        //再進行其他設定
        //...
    }
    /**
     * 設定段落對齊 方式
     * @param paragraph
     * @param pAlign
     * @param valign
     * @Author Huangxiaocong 2018年12月1日 下午8:54:43
     */
    public void setParagraphAlignInfo(XWPFParagraph paragraph, ParagraphAlignment pAlign, TextAlignment valign) {
        if(pAlign != null) {
            paragraph.setAlignment(pAlign);
        }
        if(valign != null) {
            paragraph.setVerticalAlignment(valign);
        }
    }
    /**
     * 得到段落的CTPPr
     * @param paragraph
     * @return
     * @Author Huangxiaocong 2018年12月1日 下午7:36:10
     */
    public CTPPr getParagraphCTPPr(XWPFParagraph paragraph) {
        CTPPr pPPr = null;
        if(paragraph.getCTP() != null) {
            if(paragraph.getCTP().getPPr() != null) {
                pPPr = paragraph.getCTP().getPPr();
            } else {
                pPPr = paragraph.getCTP().addNewPPr();
            }
        }
        return pPPr;
    }
    /**
     * 得到XWPFRun的CTRPr
     * @param paragraph
     * @param pRun
     * @return
     * @Author Huangxiaocong 2018年12月1日 下午7:46:01
     */
    public CTRPr getRunCTRPr(XWPFParagraph paragraph, XWPFRun pRun) {
        CTRPr ctrPr = null;
        if(pRun.getCTR() != null) {
            ctrPr = pRun.getCTR().getRPr();
            if(ctrPr == null) {
                ctrPr = pRun.getCTR().addNewRPr();
            }
        } else {
            ctrPr = paragraph.getCTP().addNewR().addNewRPr();
        }
        return ctrPr;
    }
    
    
    /**
     * 複製表格
     * @param targetTable
     * @param sourceTable
     * @Author Huangxiaocong 2018年12月1日 下午1:40:01
     */
    public void copyTable(XWPFTable targetTable, XWPFTable sourceTable) {
        //複製表格屬性
        targetTable.getCTTbl().setTblPr(sourceTable.getCTTbl().getTblPr());
        //複製行
        for(int i = 0; i < sourceTable.getRows().size(); i++) {
            XWPFTableRow targetRow = targetTable.getRow(i);
            XWPFTableRow sourceRow = sourceTable.getRow(i);
            if(targetRow == null) {
                targetTable.addRow(sourceRow);
            } else {
                copyTableRow(targetRow, sourceRow);
            }
        }
    }
    /**
     * 複製單元格
     * @param targetRow
     * @param sourceRow
     * @Author Huangxiaocong 2018年12月1日 下午1:33:22
     */
    public void copyTableRow(XWPFTableRow targetRow, XWPFTableRow sourceRow) {
        //複製樣式
        if(sourceRow != null) {
            targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
        }
        //複製單元格
        for(int i = 0; i < sourceRow.getTableCells().size(); i++) {
            XWPFTableCell tCell = targetRow.getCell(i);
            XWPFTableCell sCell = sourceRow.getCell(i);
            if(tCell == sCell) {
                tCell = targetRow.addNewTableCell();
            }
            copyTableCell(tCell, sCell);
        }
    }
    /**
     * 複製單元格(列) 從sourceCell到targetCell
     * @param targetCell
     * @param sourceCell
     * @Author Huangxiaocong 2018年12月1日 下午1:27:38
     */
    public void copyTableCell(XWPFTableCell targetCell, XWPFTableCell sourceCell) {
        //表格屬性
        if(sourceCell.getCTTc() != null) {
            targetCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());
        }
        //刪除段落
        for(int pos = 0; pos < targetCell.getParagraphs().size(); pos++) {
            targetCell.removeParagraph(pos);
        }
        //新增段落
        for(XWPFParagraph sourceParag : sourceCell.getParagraphs()) {
            XWPFParagraph targetParag = targetCell.addParagraph();
            copyParagraph(targetParag, sourceParag);
        }
    }
    /**
     * 複製段落,從sourceParag到targetParag
     * @param targetParag
     * @param sourceParag
     * @Author Huangxiaocong 2018年12月1日 下午1:16:26
     */
    public void copyParagraph(XWPFParagraph targetParag, XWPFParagraph sourceParag) {
        targetParag.getCTP().setPPr(sourceParag.getCTP().getPPr());    //設定段落樣式
        //移除所有的run
        for(int pos = targetParag.getRuns().size() - 1; pos >= 0; pos-- ) {
            targetParag.removeRun(pos);
        }
        //copy新的run
        for(XWPFRun sRun : sourceParag.getRuns()) {
            XWPFRun tarRun = targetParag.createRun();
            copyRun(tarRun, sRun);
        }
    }
    /**
     * 複製XWPFRun 從sourceRun到targetRun
     * @param targetRun
     * @param sourceRun
     * @Author Huangxiaocong 2018年12月1日 下午12:56:53
     */
    public void copyRun(XWPFRun targetRun, XWPFRun sourceRun) {
        //設定targetRun屬性
        targetRun.getCTR().setRPr(sourceRun.getCTR().getRPr());
        targetRun.setText(sourceRun.text());//設定文字
        //處理圖片
        List<XWPFPicture> pictures = sourceRun.getEmbeddedPictures();
        for(XWPFPicture picture : pictures) {
            try {
                copyPicture(targetRun, picture);
            } catch (InvalidFormatException e) {
                e.printStackTrace();
                logger.log(Level.WARNING, "copyRun", e);
            } catch (IOException e) {
                e.printStackTrace();
                logger.log(Level.WARNING, "copyRun", e);
            }
        }
    }
    /**
     * 複製圖片從sourcePicture到 targetRun(XWPFPicture --> XWPFRun)
     * @param targetRun
     * @param source
     * @throws IOException 
     * @throws InvalidFormatException 
     * @Author Huangxiaocong 2018年12月1日 下午12:57:33
     */
    public void copyPicture(XWPFRun targetRun, XWPFPicture sourcePicture) throws InvalidFormatException, IOException {
        XWPFPictureData picData = sourcePicture.getPictureData();
        String fileName = picData.getFileName();    //圖片的名稱
        InputStream picInIsData = new ByteArrayInputStream(picData.getData());    
        int picType = picData.getPictureType();
        int width = (int) sourcePicture.getCTPicture().getSpPr().getXfrm().getExt().getCx();
        int height =  (int) sourcePicture.getCTPicture().getSpPr().getXfrm().getExt().getCy();
        targetRun.addPicture(picInIsData, picType, fileName, width, height);
//        targetRun.addBreak();//分行
    }
}

 

工具類二:

package cn.hxc.myWorld.util;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.poi.xwpf.usermodel.BodyElementType;
import org.apache.poi.xwpf.usermodel.IBodyElement;
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.CTHMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHeight;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGrid;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGridCol;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;

/**
 * @Description 操作word的基本工具類
 * 2018年12月3日  上午11:12:18
 * @Author Huangxiaocong
 */
public class XWPFHelperTable {
    
    /**
     * 刪除指定位置的表格,被刪除表格後的索引位置
     * @param document
     * @param pos
     * @Author Huangxiaocong 2018年12月1日 下午10:32:43
     */
    public void deleteTableByIndex(XWPFDocument document, int pos) {
        Iterator<IBodyElement> bodyElement = document.getBodyElementsIterator();
        int eIndex = 0, tableIndex = -1;
        while(bodyElement.hasNext()) {
            IBodyElement element = bodyElement.next();
            BodyElementType elementType = element.getElementType();
            if(elementType == BodyElementType.TABLE) {
                tableIndex++;
                if(tableIndex == pos) {
                    break;
                }
            }
            eIndex++;
        }
        document.removeBodyElement(eIndex);
    }
    /**
     * 獲得指定位置的表格
     * @param document
     * @param index
     * @return
     * @Author Huangxiaocong 2018年12月1日 下午10:34:14
     */
    public XWPFTable getTableByIndex(XWPFDocument document, int index) {
        List<XWPFTable> tableList = document.getTables();
        if(tableList == null || index < 0 || index > tableList.size()) {
            return null;
        }
        return tableList.get(index);
    }
    /**
     * 得到表格的內容(第一次跨行單元格視為一個,第二次跳過跨行合併的單元格)
     * @param table
     * @return
     * @Author Huangxiaocong 2018年12月1日 下午10:46:41
     */
    public List<List<String>> getTableRConten(XWPFTable table) {
        List<List<String>> tableContextList = new ArrayList<List<String>>();
        for(int rowIndex = 0, rowLen = table.getNumberOfRows(); rowIndex < rowLen; rowIndex++) {
            XWPFTableRow row = table.getRow(rowIndex);
            List<String> cellContentList = new ArrayList<String>();
            for(int colIndex = 0, colLen = row.getTableCells().size(); colIndex < colLen; colIndex++ ) {
                XWPFTableCell cell = row.getCell(colIndex);
                CTTc ctTc = cell.getCTTc();
                if(ctTc.isSetTcPr()) {
                    CTTcPr tcPr = ctTc.getTcPr();
                    if(tcPr.isSetHMerge()) {
                        CTHMerge hMerge = tcPr.getHMerge();
                        if(STMerge.RESTART.equals(hMerge.getVal())) {
                            cellContentList.add(getTableCellContent(cell));
                        }
                    } else if(tcPr.isSetVMerge()) {
                        CTVMerge vMerge = tcPr.getVMerge();
                        if(STMerge.RESTART.equals(vMerge.getVal())) {
                            cellContentList.add(getTableCellContent(cell));
                        }
                    } else {
                        cellContentList.add(getTableCellContent(cell));
                    }
                }
            }
            tableContextList.add(cellContentList);
        }
        return tableContextList;
    }

    /**
     * 獲得一個表格的單元格的內容
     * @param cell
     * @return
     * @Author Huangxiaocong 2018年12月2日 下午7:39:23
     */
    public String getTableCellContent(XWPFTableCell cell) {
        StringBuffer sb = new StringBuffer();
        List<XWPFParagraph> cellParagList = cell.getParagraphs();
        if(cellParagList != null && cellParagList.size() > 0) {
            for(XWPFParagraph xwpfPr: cellParagList) {
                List<XWPFRun> runs = xwpfPr.getRuns();
                if(runs != null && runs.size() > 0) {
                    for(XWPFRun xwpfRun : runs) {
                        sb.append(xwpfRun.getText(0));
                    }
                }
            }
        }
        return sb.toString();
    }
    /**
     * 得到表格內容,合併後的單元格視為一個單元格
     * @param table
     * @return
     * @Author Huangxiaocong 2018年12月2日 下午7:47:19
     */
    public List<List<String>> getTableContent(XWPFTable table) {
       List<List<String>> tableContentList = new ArrayList<List<String>>();
        for (int rowIndex = 0, rowLen = table.getNumberOfRows(); rowIndex < rowLen; rowIndex++) {
          XWPFTableRow row = table.getRow(rowIndex);
          List<String> cellContentList = new ArrayList<String>();
          for (int colIndex = 0, colLen = row.getTableCells().size(); colIndex < colLen; colIndex++) {
            XWPFTableCell cell = row.getCell(colIndex);
            cellContentList.add(getTableCellContent(cell));
          }
          tableContentList.add(cellContentList);
        }
        return tableContentList;
    }
    
    /**
     * 跨列合併
     * @param table
     * @param row    所合併的行
     * @param fromCell    起始列
     * @param toCell    終止列
     * @Description
     * @Author Huangxiaocong 2018年11月26日 下午9:23:22
     */
    public 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);
            }
        }
    }
    /**
     * 跨行合併
     * @param table
     * @param col    合併的列
     * @param fromRow    起始行
     * @param toRow    終止行
     * @Description
     * @Author Huangxiaocong 2018年11月26日 下午9:09:19
     */
    public void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
        for(int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
            //第一個合併單元格用重啟合併值設定
            if(rowIndex == fromRow) {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
            } else {
                //合併第一個單元格的單元被設定為“繼續”
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

      /**
       * @Description: 建立表格,建立後表格至少有1行1列,設定列寬
       */
      public XWPFTable createTable(XWPFDocument xdoc, int rowSize, int cellSize,
          boolean isSetColWidth, int[] colWidths) {
        XWPFTable table = xdoc.createTable(rowSize, cellSize);
        if (isSetColWidth) {
          CTTbl ttbl = table.getCTTbl();
          CTTblGrid tblGrid = ttbl.addNewTblGrid();
          for (int j = 0, len = Math.min(cellSize, colWidths.length); j < len; j++) {
              CTTblGridCol gridCol = tblGrid.addNewGridCol();
              gridCol.setW(new BigInteger(String.valueOf(colWidths[j])));
          }
        }
        return table;
      }

      /**
       * @Description: 設定表格總寬度與水平對齊方式
       */
      public void setTableWidthAndHAlign(XWPFTable table, String width,
          STJc.Enum enumValue) {
        CTTblPr tblPr = getTableCTTblPr(table);
        // 表格寬度
        CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
        if (enumValue != null) {
          CTJc cTJc = tblPr.addNewJc();
          cTJc.setVal(enumValue);
        }
        // 設定寬度
        tblWidth.setW(new BigInteger(width));
        tblWidth.setType(STTblWidth.DXA);
      }

      /**
       * @Description: 得到Table的CTTblPr,不存在則新建
       */
      public CTTblPr getTableCTTblPr(XWPFTable table) {
        CTTbl ttbl = table.getCTTbl();
        // 表格屬性
        CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl.getTblPr();
        return tblPr;
      }
    
      /**
       * 設定表格行高
       * @param infoTable
       * @param heigth 高度
       * @param vertical 表格內容的顯示方式:居中、靠右...
       * @Author Huangxiaocong 2018年12月16日 
       */
      public void setTableHeight(XWPFTable infoTable, int heigth, STVerticalJc.Enum vertical) {
        List<XWPFTableRow> rows = infoTable.getRows();
        for(XWPFTableRow row : rows) {
            CTTrPr trPr = row.getCtRow().addNewTrPr();
            CTHeight ht = trPr.addNewTrHeight();
            ht.setVal(BigInteger.valueOf(heigth));
            List<XWPFTableCell> cells = row.getTableCells();
            for(XWPFTableCell tableCell : cells ) {
                CTTcPr cttcpr = tableCell.getCTTc().addNewTcPr();
                cttcpr.addNewVAlign().setVal(vertical);
            }
        }
      }
}

 

 最後是測試類:

package cn.hxc.myWorld.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.xwpf.usermodel.XWPFDocument;

import cn.hxc.myWorld.myWorld.ExportWord;

public class TestExportWord {
    
    public static void main(String[] args) throws Exception {
        ExportWord ew = new ExportWord();
        XWPFDocument document = ew.createXWPFDocument();
        List<List<Object>> list = new ArrayList<List<Object>>();
        
        List<Object> tempList = new ArrayList<Object>();
        tempList.add("姓名");
        tempList.add("黃xx");
        tempList.add("性別");
        tempList.add("男");
        tempList.add("出生日期");
        tempList.add("2018-10-10");
        list.add(tempList);
        tempList = new ArrayList<Object>();
        tempList.add("身份證號");
        tempList.add("36073xxxxxxxxxxx");
        list.add(tempList);
        tempList = new ArrayList<Object>();
        tempList.add("出生地");
        tempList.add("江西");
        tempList.add("名族");
        tempList.add("漢");
        tempList.add("婚否");
        tempList.add("否");
        list.add(tempList);
        tempList = new ArrayList<Object>();
        tempList.add("既往病史");
        tempList.add("無");
        list.add(tempList);
        
        Map<String, Object> dataList = new HashMap<String, Object>();
        dataList.put("TITLE", "個人體檢表");
        dataList.put("TABLEDATA", list);
        ew.exportCheckWord(dataList, document, "E:/expWordTest.docx");
        System.out.println("文件生成成功");
    }
}

 

效果如圖:

 

總的製作完畢。

關於最佳匯出Word的方案是在我的另一篇部落格:https://www.cnblogs.com/sun-flower1314/p/10126111.html 

好累呀 確定不點個贊?