| /* ==================================================================== |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| ==================================================================== */ |
| package org.apache.poi.xwpf.usermodel; |
| |
| import java.math.BigInteger; |
| import java.util.ArrayList; |
| import java.util.EnumMap; |
| import java.util.HashMap; |
| import java.util.List; |
| |
| import org.apache.poi.POIXMLDocumentPart; |
| import org.apache.poi.util.Internal; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblCellMar; |
| 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.STBorder; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth; |
| |
| /** |
| * <p>Sketch of XWPFTable class. Only table's text is being hold.</p> |
| * <p>Specifies the contents of a table present in the document. A table is a set |
| * of paragraphs (and other block-level content) arranged in rows and columns.</p> |
| */ |
| public class XWPFTable implements IBodyElement, ISDTContents { |
| private static EnumMap<XWPFBorderType, STBorder.Enum> xwpfBorderTypeMap; |
| // Create a map from the STBorder.Enum values to the XWPF-level enums |
| private static HashMap<Integer, XWPFBorderType> stBorderTypeMap; |
| |
| static { |
| // populate enum maps |
| xwpfBorderTypeMap = new EnumMap<XWPFBorderType, STBorder.Enum>(XWPFBorderType.class); |
| xwpfBorderTypeMap.put(XWPFBorderType.NIL, STBorder.Enum.forInt(STBorder.INT_NIL)); |
| xwpfBorderTypeMap.put(XWPFBorderType.NONE, STBorder.Enum.forInt(STBorder.INT_NONE)); |
| xwpfBorderTypeMap.put(XWPFBorderType.SINGLE, STBorder.Enum.forInt(STBorder.INT_SINGLE)); |
| xwpfBorderTypeMap.put(XWPFBorderType.THICK, STBorder.Enum.forInt(STBorder.INT_THICK)); |
| xwpfBorderTypeMap.put(XWPFBorderType.DOUBLE, STBorder.Enum.forInt(STBorder.INT_DOUBLE)); |
| xwpfBorderTypeMap.put(XWPFBorderType.DOTTED, STBorder.Enum.forInt(STBorder.INT_DOTTED)); |
| xwpfBorderTypeMap.put(XWPFBorderType.DASHED, STBorder.Enum.forInt(STBorder.INT_DASHED)); |
| xwpfBorderTypeMap.put(XWPFBorderType.DOT_DASH, STBorder.Enum.forInt(STBorder.INT_DOT_DASH)); |
| |
| stBorderTypeMap = new HashMap<Integer, XWPFBorderType>(); |
| stBorderTypeMap.put(STBorder.INT_NIL, XWPFBorderType.NIL); |
| stBorderTypeMap.put(STBorder.INT_NONE, XWPFBorderType.NONE); |
| stBorderTypeMap.put(STBorder.INT_SINGLE, XWPFBorderType.SINGLE); |
| stBorderTypeMap.put(STBorder.INT_THICK, XWPFBorderType.THICK); |
| stBorderTypeMap.put(STBorder.INT_DOUBLE, XWPFBorderType.DOUBLE); |
| stBorderTypeMap.put(STBorder.INT_DOTTED, XWPFBorderType.DOTTED); |
| stBorderTypeMap.put(STBorder.INT_DASHED, XWPFBorderType.DASHED); |
| stBorderTypeMap.put(STBorder.INT_DOT_DASH, XWPFBorderType.DOT_DASH); |
| } |
| |
| protected StringBuffer text = new StringBuffer(); |
| protected List<XWPFTableRow> tableRows; |
| |
| // Unused: UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD |
| //protected List<String> styleIDs; |
| protected IBody part; |
| private CTTbl ctTbl; |
| |
| public XWPFTable(CTTbl table, IBody part, int row, int col) { |
| this(table, part); |
| |
| for (int i = 0; i < row; i++) { |
| XWPFTableRow tabRow = (getRow(i) == null) ? createRow() : getRow(i); |
| for (int k = 0; k < col; k++) { |
| if (tabRow.getCell(k) == null) { |
| tabRow.createCell(); |
| } |
| } |
| } |
| } |
| |
| public XWPFTable(CTTbl table, IBody part) { |
| this.part = part; |
| this.ctTbl = table; |
| |
| tableRows = new ArrayList<XWPFTableRow>(); |
| |
| // is an empty table: I add one row and one column as default |
| if (table.sizeOfTrArray() == 0) |
| createEmptyTable(table); |
| |
| for (CTRow row : table.getTrArray()) { |
| StringBuilder rowText = new StringBuilder(); |
| XWPFTableRow tabRow = new XWPFTableRow(row, this); |
| tableRows.add(tabRow); |
| for (CTTc cell : row.getTcArray()) { |
| for (CTP ctp : cell.getPArray()) { |
| XWPFParagraph p = new XWPFParagraph(ctp, part); |
| if (rowText.length() > 0) { |
| rowText.append('\t'); |
| } |
| rowText.append(p.getText()); |
| } |
| } |
| if (rowText.length() > 0) { |
| this.text.append(rowText); |
| this.text.append('\n'); |
| } |
| } |
| } |
| |
| private void createEmptyTable(CTTbl table) { |
| // MINIMUM ELEMENTS FOR A TABLE |
| table.addNewTr().addNewTc().addNewP(); |
| |
| CTTblPr tblpro = table.addNewTblPr(); |
| tblpro.addNewTblW().setW(new BigInteger("0")); |
| tblpro.getTblW().setType(STTblWidth.AUTO); |
| |
| // layout |
| // tblpro.addNewTblLayout().setType(STTblLayoutType.AUTOFIT); |
| |
| // borders |
| CTTblBorders borders = tblpro.addNewTblBorders(); |
| borders.addNewBottom().setVal(STBorder.SINGLE); |
| borders.addNewInsideH().setVal(STBorder.SINGLE); |
| borders.addNewInsideV().setVal(STBorder.SINGLE); |
| borders.addNewLeft().setVal(STBorder.SINGLE); |
| borders.addNewRight().setVal(STBorder.SINGLE); |
| borders.addNewTop().setVal(STBorder.SINGLE); |
| |
| /* |
| * CTTblGrid tblgrid=table.addNewTblGrid(); |
| * tblgrid.addNewGridCol().setW(new BigInteger("2000")); |
| */ |
| getRows(); |
| } |
| |
| /** |
| * @return ctTbl object |
| */ |
| @Internal |
| public CTTbl getCTTbl() { |
| return ctTbl; |
| } |
| |
| /** |
| * Convenience method to extract text in cells. This |
| * does not extract text recursively in cells, and it does not |
| * currently include text in SDT (form) components. |
| * <p> |
| * To get all text within a table, see XWPFWordExtractor's appendTableText |
| * as an example. |
| * |
| * @return text |
| */ |
| public String getText() { |
| return text.toString(); |
| } |
| |
| public void addNewRowBetween(int start, int end) { |
| // TODO |
| } |
| |
| /** |
| * add a new column for each row in this table |
| */ |
| public void addNewCol() { |
| if (ctTbl.sizeOfTrArray() == 0) { |
| createRow(); |
| } |
| for (int i = 0; i < ctTbl.sizeOfTrArray(); i++) { |
| XWPFTableRow tabRow = new XWPFTableRow(ctTbl.getTrArray(i), this); |
| tabRow.createCell(); |
| } |
| } |
| |
| /** |
| * create a new XWPFTableRow object with as many cells as the number of columns defined in that moment |
| * |
| * @return tableRow |
| */ |
| public XWPFTableRow createRow() { |
| int sizeCol = ctTbl.sizeOfTrArray() > 0 ? ctTbl.getTrArray(0) |
| .sizeOfTcArray() : 0; |
| XWPFTableRow tabRow = new XWPFTableRow(ctTbl.addNewTr(), this); |
| addColumn(tabRow, sizeCol); |
| tableRows.add(tabRow); |
| return tabRow; |
| } |
| |
| /** |
| * @param pos - index of the row |
| * @return the row at the position specified or null if no rows is defined or if the position is greather than the max size of rows array |
| */ |
| public XWPFTableRow getRow(int pos) { |
| if (pos >= 0 && pos < ctTbl.sizeOfTrArray()) { |
| //return new XWPFTableRow(ctTbl.getTrArray(pos)); |
| return getRows().get(pos); |
| } |
| return null; |
| } |
| |
| /** |
| * @return width value |
| */ |
| public int getWidth() { |
| CTTblPr tblPr = getTrPr(); |
| return tblPr.isSetTblW() ? tblPr.getTblW().getW().intValue() : -1; |
| } |
| |
| /** |
| * @param width |
| */ |
| public void setWidth(int width) { |
| CTTblPr tblPr = getTrPr(); |
| CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW(); |
| tblWidth.setW(new BigInteger("" + width)); |
| } |
| |
| /** |
| * @return number of rows in table |
| */ |
| public int getNumberOfRows() { |
| return ctTbl.sizeOfTrArray(); |
| } |
| |
| private CTTblPr getTrPr() { |
| return (ctTbl.getTblPr() != null) ? ctTbl.getTblPr() : ctTbl |
| .addNewTblPr(); |
| } |
| |
| private void addColumn(XWPFTableRow tabRow, int sizeCol) { |
| if (sizeCol > 0) { |
| for (int i = 0; i < sizeCol; i++) { |
| tabRow.createCell(); |
| } |
| } |
| } |
| |
| /** |
| * get the StyleID of the table |
| * |
| * @return style-ID of the table |
| */ |
| public String getStyleID() { |
| String styleId = null; |
| CTTblPr tblPr = ctTbl.getTblPr(); |
| if (tblPr != null) { |
| CTString styleStr = tblPr.getTblStyle(); |
| if (styleStr != null) { |
| styleId = styleStr.getVal(); |
| } |
| } |
| return styleId; |
| } |
| |
| /** |
| * Set the table style. If the style is not defined in the document, MS Word |
| * will set the table style to "Normal". |
| * |
| * @param styleName - the style name to apply to this table |
| */ |
| public void setStyleID(String styleName) { |
| CTTblPr tblPr = getTrPr(); |
| CTString styleStr = tblPr.getTblStyle(); |
| if (styleStr == null) { |
| styleStr = tblPr.addNewTblStyle(); |
| } |
| styleStr.setVal(styleName); |
| } |
| |
| public XWPFBorderType getInsideHBorderType() { |
| XWPFBorderType bt = null; |
| |
| CTTblPr tblPr = getTrPr(); |
| if (tblPr.isSetTblBorders()) { |
| CTTblBorders ctb = tblPr.getTblBorders(); |
| if (ctb.isSetInsideH()) { |
| CTBorder border = ctb.getInsideH(); |
| bt = stBorderTypeMap.get(border.getVal().intValue()); |
| } |
| } |
| return bt; |
| } |
| |
| public int getInsideHBorderSize() { |
| int size = -1; |
| |
| CTTblPr tblPr = getTrPr(); |
| if (tblPr.isSetTblBorders()) { |
| CTTblBorders ctb = tblPr.getTblBorders(); |
| if (ctb.isSetInsideH()) { |
| CTBorder border = ctb.getInsideH(); |
| size = border.getSz().intValue(); |
| } |
| } |
| return size; |
| } |
| |
| public int getInsideHBorderSpace() { |
| int space = -1; |
| |
| CTTblPr tblPr = getTrPr(); |
| if (tblPr.isSetTblBorders()) { |
| CTTblBorders ctb = tblPr.getTblBorders(); |
| if (ctb.isSetInsideH()) { |
| CTBorder border = ctb.getInsideH(); |
| space = border.getSpace().intValue(); |
| } |
| } |
| return space; |
| } |
| |
| public String getInsideHBorderColor() { |
| String color = null; |
| |
| CTTblPr tblPr = getTrPr(); |
| if (tblPr.isSetTblBorders()) { |
| CTTblBorders ctb = tblPr.getTblBorders(); |
| if (ctb.isSetInsideH()) { |
| CTBorder border = ctb.getInsideH(); |
| color = border.xgetColor().getStringValue(); |
| } |
| } |
| return color; |
| } |
| |
| public XWPFBorderType getInsideVBorderType() { |
| XWPFBorderType bt = null; |
| |
| CTTblPr tblPr = getTrPr(); |
| if (tblPr.isSetTblBorders()) { |
| CTTblBorders ctb = tblPr.getTblBorders(); |
| if (ctb.isSetInsideV()) { |
| CTBorder border = ctb.getInsideV(); |
| bt = stBorderTypeMap.get(border.getVal().intValue()); |
| } |
| } |
| return bt; |
| } |
| |
| public int getInsideVBorderSize() { |
| int size = -1; |
| |
| CTTblPr tblPr = getTrPr(); |
| if (tblPr.isSetTblBorders()) { |
| CTTblBorders ctb = tblPr.getTblBorders(); |
| if (ctb.isSetInsideV()) { |
| CTBorder border = ctb.getInsideV(); |
| size = border.getSz().intValue(); |
| } |
| } |
| return size; |
| } |
| |
| public int getInsideVBorderSpace() { |
| int space = -1; |
| |
| CTTblPr tblPr = getTrPr(); |
| if (tblPr.isSetTblBorders()) { |
| CTTblBorders ctb = tblPr.getTblBorders(); |
| if (ctb.isSetInsideV()) { |
| CTBorder border = ctb.getInsideV(); |
| space = border.getSpace().intValue(); |
| } |
| } |
| return space; |
| } |
| |
| public String getInsideVBorderColor() { |
| String color = null; |
| |
| CTTblPr tblPr = getTrPr(); |
| if (tblPr.isSetTblBorders()) { |
| CTTblBorders ctb = tblPr.getTblBorders(); |
| if (ctb.isSetInsideV()) { |
| CTBorder border = ctb.getInsideV(); |
| color = border.xgetColor().getStringValue(); |
| } |
| } |
| return color; |
| } |
| |
| public int getRowBandSize() { |
| int size = 0; |
| CTTblPr tblPr = getTrPr(); |
| if (tblPr.isSetTblStyleRowBandSize()) { |
| CTDecimalNumber rowSize = tblPr.getTblStyleRowBandSize(); |
| size = rowSize.getVal().intValue(); |
| } |
| return size; |
| } |
| |
| public void setRowBandSize(int size) { |
| CTTblPr tblPr = getTrPr(); |
| CTDecimalNumber rowSize = tblPr.isSetTblStyleRowBandSize() ? tblPr.getTblStyleRowBandSize() : tblPr.addNewTblStyleRowBandSize(); |
| rowSize.setVal(BigInteger.valueOf(size)); |
| } |
| |
| public int getColBandSize() { |
| int size = 0; |
| CTTblPr tblPr = getTrPr(); |
| if (tblPr.isSetTblStyleColBandSize()) { |
| CTDecimalNumber colSize = tblPr.getTblStyleColBandSize(); |
| size = colSize.getVal().intValue(); |
| } |
| return size; |
| } |
| |
| public void setColBandSize(int size) { |
| CTTblPr tblPr = getTrPr(); |
| CTDecimalNumber colSize = tblPr.isSetTblStyleColBandSize() ? tblPr.getTblStyleColBandSize() : tblPr.addNewTblStyleColBandSize(); |
| colSize.setVal(BigInteger.valueOf(size)); |
| } |
| |
| public void setInsideHBorder(XWPFBorderType type, int size, int space, String rgbColor) { |
| CTTblPr tblPr = getTrPr(); |
| CTTblBorders ctb = tblPr.isSetTblBorders() ? tblPr.getTblBorders() : tblPr.addNewTblBorders(); |
| CTBorder b = ctb.isSetInsideH() ? ctb.getInsideH() : ctb.addNewInsideH(); |
| b.setVal(xwpfBorderTypeMap.get(type)); |
| b.setSz(BigInteger.valueOf(size)); |
| b.setSpace(BigInteger.valueOf(space)); |
| b.setColor(rgbColor); |
| } |
| |
| public void setInsideVBorder(XWPFBorderType type, int size, int space, String rgbColor) { |
| CTTblPr tblPr = getTrPr(); |
| CTTblBorders ctb = tblPr.isSetTblBorders() ? tblPr.getTblBorders() : tblPr.addNewTblBorders(); |
| CTBorder b = ctb.isSetInsideV() ? ctb.getInsideV() : ctb.addNewInsideV(); |
| b.setVal(xwpfBorderTypeMap.get(type)); |
| b.setSz(BigInteger.valueOf(size)); |
| b.setSpace(BigInteger.valueOf(space)); |
| b.setColor(rgbColor); |
| } |
| |
| public int getCellMarginTop() { |
| int margin = 0; |
| CTTblPr tblPr = getTrPr(); |
| CTTblCellMar tcm = tblPr.getTblCellMar(); |
| if (tcm != null) { |
| CTTblWidth tw = tcm.getTop(); |
| if (tw != null) { |
| margin = tw.getW().intValue(); |
| } |
| } |
| return margin; |
| } |
| |
| public int getCellMarginLeft() { |
| int margin = 0; |
| CTTblPr tblPr = getTrPr(); |
| CTTblCellMar tcm = tblPr.getTblCellMar(); |
| if (tcm != null) { |
| CTTblWidth tw = tcm.getLeft(); |
| if (tw != null) { |
| margin = tw.getW().intValue(); |
| } |
| } |
| return margin; |
| } |
| |
| public int getCellMarginBottom() { |
| int margin = 0; |
| CTTblPr tblPr = getTrPr(); |
| CTTblCellMar tcm = tblPr.getTblCellMar(); |
| if (tcm != null) { |
| CTTblWidth tw = tcm.getBottom(); |
| if (tw != null) { |
| margin = tw.getW().intValue(); |
| } |
| } |
| return margin; |
| } |
| |
| public int getCellMarginRight() { |
| int margin = 0; |
| CTTblPr tblPr = getTrPr(); |
| CTTblCellMar tcm = tblPr.getTblCellMar(); |
| if (tcm != null) { |
| CTTblWidth tw = tcm.getRight(); |
| if (tw != null) { |
| margin = tw.getW().intValue(); |
| } |
| } |
| return margin; |
| } |
| |
| public void setCellMargins(int top, int left, int bottom, int right) { |
| CTTblPr tblPr = getTrPr(); |
| CTTblCellMar tcm = tblPr.isSetTblCellMar() ? tblPr.getTblCellMar() : tblPr.addNewTblCellMar(); |
| |
| CTTblWidth tw = tcm.isSetLeft() ? tcm.getLeft() : tcm.addNewLeft(); |
| tw.setType(STTblWidth.DXA); |
| tw.setW(BigInteger.valueOf(left)); |
| |
| tw = tcm.isSetTop() ? tcm.getTop() : tcm.addNewTop(); |
| tw.setType(STTblWidth.DXA); |
| tw.setW(BigInteger.valueOf(top)); |
| |
| tw = tcm.isSetBottom() ? tcm.getBottom() : tcm.addNewBottom(); |
| tw.setType(STTblWidth.DXA); |
| tw.setW(BigInteger.valueOf(bottom)); |
| |
| tw = tcm.isSetRight() ? tcm.getRight() : tcm.addNewRight(); |
| tw.setType(STTblWidth.DXA); |
| tw.setW(BigInteger.valueOf(right)); |
| } |
| |
| /** |
| * add a new Row to the table |
| * |
| * @param row the row which should be added |
| */ |
| public void addRow(XWPFTableRow row) { |
| ctTbl.addNewTr(); |
| ctTbl.setTrArray(getNumberOfRows() - 1, row.getCtRow()); |
| tableRows.add(row); |
| } |
| |
| /** |
| * add a new Row to the table |
| * at position pos |
| * |
| * @param row the row which should be added |
| */ |
| public boolean addRow(XWPFTableRow row, int pos) { |
| if (pos >= 0 && pos <= tableRows.size()) { |
| ctTbl.insertNewTr(pos); |
| ctTbl.setTrArray(pos, row.getCtRow()); |
| tableRows.add(pos, row); |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * inserts a new tablerow |
| * |
| * @param pos |
| * @return the inserted row |
| */ |
| public XWPFTableRow insertNewTableRow(int pos) { |
| if (pos >= 0 && pos <= tableRows.size()) { |
| CTRow row = ctTbl.insertNewTr(pos); |
| XWPFTableRow tableRow = new XWPFTableRow(row, this); |
| tableRows.add(pos, tableRow); |
| return tableRow; |
| } |
| return null; |
| } |
| |
| /** |
| * Remove a row at position pos from the table |
| * |
| * @param pos position the Row in the Table |
| */ |
| public boolean removeRow(int pos) throws IndexOutOfBoundsException { |
| if (pos >= 0 && pos < tableRows.size()) { |
| if (ctTbl.sizeOfTrArray() > 0) { |
| ctTbl.removeTr(pos); |
| } |
| tableRows.remove(pos); |
| return true; |
| } |
| return false; |
| } |
| |
| public List<XWPFTableRow> getRows() { |
| return tableRows; |
| } |
| |
| /** |
| * returns the type of the BodyElement Table |
| * |
| * @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType() |
| */ |
| public BodyElementType getElementType() { |
| return BodyElementType.TABLE; |
| } |
| |
| public IBody getBody() { |
| return part; |
| } |
| |
| /** |
| * returns the part of the bodyElement |
| * |
| * @see org.apache.poi.xwpf.usermodel.IBody#getPart() |
| */ |
| public POIXMLDocumentPart getPart() { |
| if (part != null) { |
| return part.getPart(); |
| } |
| return null; |
| } |
| |
| /** |
| * returns the partType of the bodyPart which owns the bodyElement |
| * |
| * @see org.apache.poi.xwpf.usermodel.IBody#getPartType() |
| */ |
| public BodyType getPartType() { |
| return part.getPartType(); |
| } |
| |
| /** |
| * returns the XWPFRow which belongs to the CTRow row |
| * if this row is not existing in the table null will be returned |
| */ |
| public XWPFTableRow getRow(CTRow row) { |
| for (int i = 0; i < getRows().size(); i++) { |
| if (getRows().get(i).getCtRow() == row) return getRow(i); |
| } |
| return null; |
| } |
| |
| // Create a map from this XWPF-level enum to the STBorder.Enum values |
| public static enum XWPFBorderType { |
| NIL, NONE, SINGLE, THICK, DOUBLE, DOTTED, DASHED, DOT_DASH |
| } |
| } |