You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

XSLFTable.java 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * ====================================================================
  3. * Licensed to the Apache Software Foundation (ASF) under one or more
  4. * contributor license agreements. See the NOTICE file distributed with
  5. * this work for additional information regarding copyright ownership.
  6. * The ASF licenses this file to You under the Apache License, Version 2.0
  7. * (the "License"); you may not use this file except in compliance with
  8. * the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. * ====================================================================
  18. */
  19. package org.apache.poi.xslf.usermodel;
  20. import java.util.ArrayList;
  21. import java.util.Collections;
  22. import java.util.Iterator;
  23. import java.util.List;
  24. import javax.xml.namespace.QName;
  25. import org.apache.poi.POIXMLDocumentPart;
  26. import org.apache.poi.POIXMLException;
  27. import org.apache.poi.sl.usermodel.TableShape;
  28. import org.apache.poi.util.Internal;
  29. import org.apache.poi.util.Units;
  30. import org.apache.xmlbeans.XmlCursor;
  31. import org.apache.xmlbeans.XmlException;
  32. import org.apache.xmlbeans.XmlObject;
  33. import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl;
  34. import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;
  35. import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
  36. import org.openxmlformats.schemas.drawingml.x2006.main.CTTable;
  37. import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow;
  38. import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
  39. import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrameNonVisual;
  40. /**
  41. * Represents a table in a .pptx presentation
  42. *
  43. * @author Yegor Kozlov
  44. */
  45. public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow>,
  46. TableShape<XSLFShape,XSLFTextParagraph> {
  47. static String TABLE_URI = "http://schemas.openxmlformats.org/drawingml/2006/table";
  48. private CTTable _table;
  49. private List<XSLFTableRow> _rows;
  50. @SuppressWarnings("deprecation")
  51. /*package*/ XSLFTable(CTGraphicalObjectFrame shape, XSLFSheet sheet){
  52. super(shape, sheet);
  53. XmlObject[] rs = shape.getGraphic().getGraphicData()
  54. .selectPath("declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' ./a:tbl");
  55. if (rs.length == 0) {
  56. throw new IllegalStateException("a:tbl element was not found in\n " + shape.getGraphic().getGraphicData());
  57. }
  58. // Pesky XmlBeans bug - see Bugzilla #49934
  59. // it never happens when using the full ooxml-schemas jar but may happen with the abridged poi-ooxml-schemas
  60. if(rs[0] instanceof XmlAnyTypeImpl){
  61. try {
  62. rs[0] = CTTable.Factory.parse(rs[0].toString(), POIXMLDocumentPart.DEFAULT_XML_OPTIONS);
  63. }catch (XmlException e){
  64. throw new POIXMLException(e);
  65. }
  66. }
  67. _table = (CTTable) rs[0];
  68. CTTableRow[] trArray = _table.getTrArray();
  69. _rows = new ArrayList<XSLFTableRow>(trArray.length);
  70. for(CTTableRow row : trArray) _rows.add(new XSLFTableRow(row, this));
  71. }
  72. @Override
  73. public XSLFTableCell getCell(int row, int col) {
  74. return getRows().get(row).getCells().get(col);
  75. }
  76. @Internal
  77. public CTTable getCTTable(){
  78. return _table;
  79. }
  80. @Override
  81. public int getNumberOfColumns() {
  82. return _table.getTblGrid().sizeOfGridColArray();
  83. }
  84. @Override
  85. public int getNumberOfRows() {
  86. return _table.sizeOfTrArray();
  87. }
  88. @Override
  89. public double getColumnWidth(int idx){
  90. return Units.toPoints(
  91. _table.getTblGrid().getGridColArray(idx).getW());
  92. }
  93. @Override
  94. public void setColumnWidth(int idx, double width) {
  95. _table.getTblGrid().getGridColArray(idx).setW(Units.toEMU(width));
  96. }
  97. @Override
  98. public double getRowHeight(int row) {
  99. return Units.toPoints(_table.getTrArray(row).getH());
  100. }
  101. @Override
  102. public void setRowHeight(int row, double height) {
  103. _table.getTrArray(row).setH(Units.toEMU(height));
  104. }
  105. public Iterator<XSLFTableRow> iterator(){
  106. return _rows.iterator();
  107. }
  108. public List<XSLFTableRow> getRows(){
  109. return Collections.unmodifiableList(_rows);
  110. }
  111. public XSLFTableRow addRow(){
  112. CTTableRow tr = _table.addNewTr();
  113. XSLFTableRow row = new XSLFTableRow(tr, this);
  114. row.setHeight(20.0); // default height is 20 points
  115. _rows.add(row);
  116. return row;
  117. }
  118. static CTGraphicalObjectFrame prototype(int shapeId){
  119. CTGraphicalObjectFrame frame = CTGraphicalObjectFrame.Factory.newInstance();
  120. CTGraphicalObjectFrameNonVisual nvGr = frame.addNewNvGraphicFramePr();
  121. CTNonVisualDrawingProps cnv = nvGr.addNewCNvPr();
  122. cnv.setName("Table " + shapeId);
  123. cnv.setId(shapeId + 1);
  124. nvGr.addNewCNvGraphicFramePr().addNewGraphicFrameLocks().setNoGrp(true);
  125. nvGr.addNewNvPr();
  126. frame.addNewXfrm();
  127. CTGraphicalObjectData gr = frame.addNewGraphic().addNewGraphicData();
  128. XmlCursor cursor = gr.newCursor();
  129. cursor.toNextToken();
  130. cursor.beginElement(new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "tbl"));
  131. cursor.beginElement(new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "tblPr"));
  132. cursor.toNextToken();
  133. cursor.beginElement(new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "tblGrid"));
  134. cursor.dispose();
  135. gr.setUri(TABLE_URI);
  136. return frame;
  137. }
  138. /**
  139. * Merge cells of a table
  140. */
  141. public void mergeCells(int firstRow, int lastRow, int firstCol, int lastCol) {
  142. if(firstRow > lastRow) {
  143. throw new IllegalArgumentException(
  144. "Cannot merge, first row > last row : "
  145. + firstRow + " > " + lastRow
  146. );
  147. }
  148. if(firstCol > lastCol) {
  149. throw new IllegalArgumentException(
  150. "Cannot merge, first column > last column : "
  151. + firstCol + " > " + lastCol
  152. );
  153. }
  154. int rowSpan = (lastRow - firstRow) + 1;
  155. boolean mergeRowRequired = rowSpan > 1;
  156. int colSpan = (lastCol - firstCol) + 1;
  157. boolean mergeColumnRequired = colSpan > 1;
  158. for(int i = firstRow; i <= lastRow; i++) {
  159. XSLFTableRow row = _rows.get(i);
  160. for(int colPos = firstCol; colPos <= lastCol; colPos++) {
  161. XSLFTableCell cell = row.getCells().get(colPos);
  162. if(mergeRowRequired) {
  163. if(i == firstRow) {
  164. cell.setRowSpan(rowSpan);
  165. } else {
  166. cell.setVMerge(true);
  167. }
  168. }
  169. if(mergeColumnRequired) {
  170. if(colPos == firstCol) {
  171. cell.setGridSpan(colSpan);
  172. } else {
  173. cell.setHMerge(true);
  174. }
  175. }
  176. }
  177. }
  178. }
  179. }