mirror of https://github.com/apache/poi.git
[bug-62055] Fix XSSFImportFromXML table resize. Thanks to Leonard Kappe. This closes #99
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1825315 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
02719ac4ba
commit
4ad4d76241
|
@ -75,9 +75,9 @@ public class CreateTable {
|
|||
}
|
||||
}
|
||||
// Create the columns
|
||||
table.addColumn();
|
||||
table.addColumn();
|
||||
table.addColumn();
|
||||
table.createColumn("Column 1");
|
||||
table.createColumn("Column 2");
|
||||
table.createColumn("Column 3");
|
||||
|
||||
// Set which area the table should be placed in
|
||||
AreaReference reference = wb.getCreationHelper().createAreaReference(
|
||||
|
|
|
@ -50,9 +50,9 @@ import org.apache.poi.xssf.usermodel.XSSFMap;
|
|||
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFTable;
|
||||
import org.apache.poi.xssf.usermodel.XSSFTableColumn;
|
||||
import org.apache.poi.xssf.usermodel.helpers.XSSFSingleXmlCell;
|
||||
import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
@ -175,14 +175,11 @@ public class XSSFExportToXml implements Comparator<String>{
|
|||
// Exports elements and attributes mapped with tables
|
||||
if (table!=null) {
|
||||
|
||||
List<CTTableColumn> tableColumns = table.getCTTable().getTableColumns().getTableColumnList();
|
||||
List<XSSFTableColumn> tableColumns = table.getColumns();
|
||||
|
||||
XSSFSheet sheet = table.getXSSFSheet();
|
||||
|
||||
int startRow = table.getStartCellReference().getRow();
|
||||
// In mappings created with Microsoft Excel the first row contains the table header and must be skipped
|
||||
startRow +=1;
|
||||
|
||||
int startRow = table.getStartCellReference().getRow() + table.getHeaderRowCount();
|
||||
int endRow = table.getEndCellReference().getRow();
|
||||
|
||||
for(int i = startRow; i<= endRow; i++) {
|
||||
|
@ -191,16 +188,12 @@ public class XSSFExportToXml implements Comparator<String>{
|
|||
Node tableRootNode = getNodeByXPath(table.getCommonXpath(), doc.getFirstChild(), doc, true);
|
||||
|
||||
short startColumnIndex = table.getStartCellReference().getCol();
|
||||
for (int j = startColumnIndex; j <= table.getEndCellReference().getCol(); j++) {
|
||||
XSSFCell cell = row.getCell(j);
|
||||
for (XSSFTableColumn tableColumn : tableColumns) {
|
||||
XSSFCell cell = row.getCell(startColumnIndex + tableColumn.getColumnIndex());
|
||||
if (cell != null) {
|
||||
int tableColumnIndex = j - startColumnIndex;
|
||||
if (tableColumnIndex < tableColumns.size()) {
|
||||
CTTableColumn ctTableColumn = tableColumns.get(tableColumnIndex);
|
||||
if (ctTableColumn.getXmlColumnPr() != null) {
|
||||
XSSFXmlColumnPr pointer = new XSSFXmlColumnPr(table, ctTableColumn,
|
||||
ctTableColumn.getXmlColumnPr());
|
||||
String localXPath = pointer.getLocalXPath();
|
||||
XSSFXmlColumnPr xmlColumnPr = tableColumn.getXmlColumnPr();
|
||||
if (xmlColumnPr != null) {
|
||||
String localXPath = xmlColumnPr.getLocalXPath();
|
||||
Node currentNode = getNodeByXPath(localXPath,tableRootNode,doc,false);
|
||||
mapCellOnNode(cell, currentNode);
|
||||
}
|
||||
|
@ -208,7 +201,6 @@ public class XSSFExportToXml implements Comparator<String>{
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /*else {
|
||||
// TODO: implement filtering management in xpath
|
||||
}*/
|
||||
|
|
|
@ -47,6 +47,7 @@ import org.apache.poi.xssf.usermodel.XSSFCell;
|
|||
import org.apache.poi.xssf.usermodel.XSSFMap;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||
import org.apache.poi.xssf.usermodel.XSSFTable;
|
||||
import org.apache.poi.xssf.usermodel.XSSFTableColumn;
|
||||
import org.apache.poi.xssf.usermodel.helpers.XSSFSingleXmlCell;
|
||||
import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXmlDataType;
|
||||
|
@ -124,8 +125,10 @@ public class XSSFImportFromXML {
|
|||
|
||||
String commonXPath = table.getCommonXpath();
|
||||
NodeList result = (NodeList) xpath.evaluate(commonXPath, doc, XPathConstants.NODESET);
|
||||
int rowOffset = table.getStartCellReference().getRow() + 1;// the first row contains the table header
|
||||
int columnOffset = table.getStartCellReference().getCol() - 1;
|
||||
int rowOffset = table.getStartCellReference().getRow() + table.getHeaderRowCount();
|
||||
int columnOffset = table.getStartCellReference().getCol();
|
||||
|
||||
table.setDataRowCount(result.getLength());
|
||||
|
||||
for (int i = 0; i < result.getLength(); i++) {
|
||||
|
||||
|
@ -133,13 +136,18 @@ public class XSSFImportFromXML {
|
|||
// OpenOffice part 4: chapter 3.5.1.7)
|
||||
|
||||
Node singleNode = result.item(i).cloneNode(true);
|
||||
for (XSSFXmlColumnPr xmlColumnPr : table.getXmlColumnPrs()) {
|
||||
|
||||
int localColumnId = (int) xmlColumnPr.getId();
|
||||
for (XSSFTableColumn tableColum : table.getColumns()) {
|
||||
|
||||
XSSFXmlColumnPr xmlColumnPr = tableColum.getXmlColumnPr();
|
||||
if(xmlColumnPr == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int rowId = rowOffset + i;
|
||||
int columnId = columnOffset + localColumnId;
|
||||
int columnId = columnOffset + tableColum.getColumnIndex();
|
||||
String localXPath = xmlColumnPr.getLocalXPath();
|
||||
localXPath = localXPath.substring(localXPath.substring(1).indexOf('/') + 2);
|
||||
localXPath = localXPath.substring(localXPath.indexOf('/', 1) + 1);
|
||||
|
||||
// TODO: convert the data to the cell format
|
||||
String value = (String) xpath.evaluate(localXPath, singleNode, XPathConstants.STRING);
|
||||
|
@ -161,6 +169,8 @@ public class XSSFImportFromXML {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static enum DataType {
|
||||
BOOLEAN(STXmlDataType.BOOLEAN), //
|
||||
DOUBLE(STXmlDataType.DOUBLE), //
|
||||
|
|
|
@ -80,6 +80,7 @@ import org.apache.poi.util.Beta;
|
|||
import org.apache.poi.util.Internal;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.Removal;
|
||||
import org.apache.poi.util.Units;
|
||||
import org.apache.poi.xssf.model.CommentsTable;
|
||||
import org.apache.poi.xssf.usermodel.XSSFPivotTable.PivotTableReferenceConfigurator;
|
||||
|
@ -4057,9 +4058,27 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a new Table, and associates it with this Sheet
|
||||
* Creates a new Table, and associates it with this Sheet. The table does
|
||||
* not yet have an area defined and needs to be initialized by calling
|
||||
* {@link XSSFTable#setArea(AreaReference)}.
|
||||
*
|
||||
* @deprecated Use {@link #createTable(AreaReference))} instead
|
||||
*/
|
||||
@Deprecated
|
||||
@Removal(version = "4.2.0")
|
||||
public XSSFTable createTable() {
|
||||
return createTable(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Table, and associates it with this Sheet.
|
||||
*
|
||||
* @param tableArea
|
||||
* the area that the table should cover, should not be {@null}
|
||||
* @return the created table
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public XSSFTable createTable(AreaReference tableArea) {
|
||||
if (!worksheet.isSetTableParts()) {
|
||||
worksheet.addNewTableParts();
|
||||
}
|
||||
|
@ -4093,6 +4112,10 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
|||
|
||||
tables.put(tbl.getId(), table);
|
||||
|
||||
if(tableArea != null) {
|
||||
table.setArea(tableArea);
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.io.InputStream;
|
|||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -32,12 +33,14 @@ import org.apache.poi.POIXMLDocumentPart;
|
|||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.ss.SpreadsheetVersion;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellType;
|
||||
import org.apache.poi.ss.usermodel.DataFormatter;
|
||||
import org.apache.poi.ss.usermodel.Table;
|
||||
import org.apache.poi.ss.usermodel.TableStyleInfo;
|
||||
import org.apache.poi.ss.util.AreaReference;
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.util.Internal;
|
||||
import org.apache.poi.util.Removal;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
|
@ -48,12 +51,12 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.TableDocument;
|
|||
|
||||
/**
|
||||
*
|
||||
* This class implements the Table Part (Open Office XML Part 4:
|
||||
* chapter 3.5.1)
|
||||
* This class implements the Table Part (Open Office XML Part 4: chapter 3.5.1)
|
||||
*
|
||||
* This implementation works under the assumption that a table contains mappings to a subtree of an XML.
|
||||
* The root element of this subtree an occur multiple times (one for each row of the table). The child nodes
|
||||
* of the root element can be only attributes or element with maxOccurs=1 property set
|
||||
* Columns of this table may contains mappings to a subtree of an XML. The root
|
||||
* element of this subtree can occur multiple times (one for each row of the
|
||||
* table). The child nodes of the root element can be only attributes or
|
||||
* elements with maxOccurs=1 property set.
|
||||
*
|
||||
*
|
||||
* @author Roberto Manicardi
|
||||
|
@ -61,8 +64,8 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.TableDocument;
|
|||
public class XSSFTable extends POIXMLDocumentPart implements Table {
|
||||
|
||||
private CTTable ctTable;
|
||||
private transient List<XSSFXmlColumnPr> xmlColumnPr;
|
||||
private transient CTTableColumn[] ctColumns;
|
||||
private transient List<XSSFXmlColumnPr> xmlColumnPrs;
|
||||
private transient List<XSSFTableColumn> tableColumns;
|
||||
private transient HashMap<String, Integer> columnMap;
|
||||
private transient CellReference startCellReference;
|
||||
private transient CellReference endCellReference;
|
||||
|
@ -156,18 +159,6 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* caches table columns for performance.
|
||||
* Updated via updateHeaders
|
||||
* @since 3.15 beta 2
|
||||
*/
|
||||
private CTTableColumn[] getTableColumns() {
|
||||
if (ctColumns == null) {
|
||||
ctColumns = ctTable.getTableColumns().getTableColumnArray();
|
||||
}
|
||||
return ctColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Calculates the xpath of the root element for the table. This will be the common part
|
||||
|
@ -179,9 +170,9 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
|||
public String getCommonXpath() {
|
||||
if (commonXPath == null) {
|
||||
String[] commonTokens = {};
|
||||
for (CTTableColumn column : getTableColumns()) {
|
||||
for (XSSFTableColumn column : getColumns()) {
|
||||
if (column.getXmlColumnPr()!=null) {
|
||||
String xpath = column.getXmlColumnPr().getXpath();
|
||||
String xpath = column.getXmlColumnPr().getXPath();
|
||||
String[] tokens = xpath.split("/");
|
||||
if (commonTokens.length==0) {
|
||||
commonTokens = tokens;
|
||||
|
@ -210,45 +201,166 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
|||
return commonXPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note this list is static - once read, it does not notice later changes to the underlying column structures
|
||||
* To clear the cache, call {@link #updateHeaders}
|
||||
* @return List of XSSFTableColumn
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public List<XSSFTableColumn> getColumns() {
|
||||
if (tableColumns == null) {
|
||||
List<XSSFTableColumn> columns = new ArrayList<>();
|
||||
CTTableColumns ctTableColumns = ctTable.getTableColumns();
|
||||
if (ctTableColumns != null) {
|
||||
for (CTTableColumn column : ctTableColumns.getTableColumnList()) {
|
||||
XSSFTableColumn tableColumn = new XSSFTableColumn(this, column);
|
||||
columns.add(tableColumn);
|
||||
}
|
||||
}
|
||||
tableColumns = Collections.unmodifiableList(columns);
|
||||
}
|
||||
return tableColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note this list is static - once read, it does not notice later changes to the underlying column structures
|
||||
* To clear the cache, call {@link #updateHeaders}
|
||||
*
|
||||
* @deprecated Use {@link XSSFTableColumn#getXmlColumnPr()} instead.
|
||||
*
|
||||
* @return List of XSSFXmlColumnPr
|
||||
*/
|
||||
@Deprecated
|
||||
@Removal(version="4.2.0")
|
||||
public List<XSSFXmlColumnPr> getXmlColumnPrs() {
|
||||
if (xmlColumnPr==null) {
|
||||
xmlColumnPr = new ArrayList<>();
|
||||
for (CTTableColumn column: getTableColumns()) {
|
||||
if (column.getXmlColumnPr()!=null) {
|
||||
XSSFXmlColumnPr columnPr = new XSSFXmlColumnPr(this,column,column.getXmlColumnPr());
|
||||
xmlColumnPr.add(columnPr);
|
||||
if (xmlColumnPrs == null) {
|
||||
xmlColumnPrs = new ArrayList<>();
|
||||
for (XSSFTableColumn column: getColumns()) {
|
||||
XSSFXmlColumnPr xmlColumnPr = column.getXmlColumnPr();
|
||||
if (xmlColumnPr != null) {
|
||||
xmlColumnPrs.add(xmlColumnPr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return xmlColumnPr;
|
||||
return xmlColumnPrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds another column to the table.
|
||||
* Add a new column to the right end of the table.
|
||||
*
|
||||
* Warning - Return type likely to change!
|
||||
* @param columnName
|
||||
* the unique name of the column, must not be {@code null}
|
||||
* @return the created table column
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@Internal("Return type likely to change")
|
||||
public void addColumn() {
|
||||
public XSSFTableColumn createColumn(String columnName) {
|
||||
return createColumn(columnName, getColumnCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new column to the table.
|
||||
*
|
||||
* @param columnName
|
||||
* the unique name of the column, or {@code null} for a generated name
|
||||
* @param columnIndex
|
||||
* the 0-based position of the column in the table
|
||||
* @return the created table column
|
||||
* @throws IllegalArgumentException
|
||||
* if the column name is not unique or missing or if the column
|
||||
* can't be created at the given index
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public XSSFTableColumn createColumn(String columnName, int columnIndex) {
|
||||
|
||||
int columnCount = getColumnCount();
|
||||
if(columnIndex < 0 || columnIndex > columnCount) {
|
||||
throw new IllegalArgumentException("Column index out of bounds");
|
||||
}
|
||||
|
||||
// Ensure we have Table Columns
|
||||
CTTableColumns columns = ctTable.getTableColumns();
|
||||
if (columns == null) {
|
||||
columns = ctTable.addNewTableColumns();
|
||||
}
|
||||
|
||||
// Add another Column, and give it a sensible ID
|
||||
CTTableColumn column = columns.addNewTableColumn();
|
||||
int num = columns.sizeOfTableColumnArray();
|
||||
columns.setCount(num);
|
||||
column.setId(num);
|
||||
// check if name is unique and calculate unique column id
|
||||
long nextColumnId = 1;
|
||||
for (XSSFTableColumn tableColumn : getColumns()) {
|
||||
if (columnName != null && columnName.equalsIgnoreCase(tableColumn.getName())) {
|
||||
throw new IllegalArgumentException("Column '" + columnName
|
||||
+ "' already exists. Column names must be unique per table.");
|
||||
}
|
||||
nextColumnId = Math.max(nextColumnId, tableColumn.getId());
|
||||
}
|
||||
|
||||
// Have the Headers updated if possible
|
||||
// Add the new Column
|
||||
CTTableColumn column = columns.insertNewTableColumn(columnIndex);
|
||||
columns.setCount(columns.sizeOfTableColumnArray());
|
||||
|
||||
column.setId(nextColumnId);
|
||||
if(columnName != null) {
|
||||
column.setName(columnName);
|
||||
} else {
|
||||
column.setName("Column " + nextColumnId);
|
||||
}
|
||||
|
||||
if (ctTable.getRef() != null) {
|
||||
// calculate new area
|
||||
int newColumnCount = columnCount + 1;
|
||||
CellReference tableStart = getStartCellReference();
|
||||
CellReference tableEnd = getEndCellReference();
|
||||
SpreadsheetVersion version = getXSSFSheet().getWorkbook().getSpreadsheetVersion();
|
||||
CellReference newTableEnd = new CellReference(tableEnd.getRow(),
|
||||
tableStart.getCol() + newColumnCount - 1);
|
||||
AreaReference newTableArea = new AreaReference(tableStart, newTableEnd, version);
|
||||
|
||||
setCellRef(newTableArea);
|
||||
}
|
||||
|
||||
updateHeaders();
|
||||
|
||||
return getColumns().get(columnIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a column from the table.
|
||||
*
|
||||
* @param column
|
||||
* the column to remove
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public void removeColumn(XSSFTableColumn column) {
|
||||
int columnIndex = getColumns().indexOf(column);
|
||||
if (columnIndex >= 0) {
|
||||
ctTable.getTableColumns().removeTableColumn(columnIndex);
|
||||
updateReferences();
|
||||
updateHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a column from the table.
|
||||
*
|
||||
* @param columnIndex
|
||||
* the 0-based position of the column in the table
|
||||
* @throws IllegalArgumentException
|
||||
* if no column at the index exists or if the table has only a
|
||||
* single column
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public void removeColumn(int columnIndex) {
|
||||
if (columnIndex < 0 || columnIndex > getColumnCount() - 1) {
|
||||
throw new IllegalArgumentException("Column index out of bounds");
|
||||
}
|
||||
|
||||
if(getColumnCount() == 1) {
|
||||
throw new IllegalArgumentException("Table must have at least one column");
|
||||
}
|
||||
|
||||
CTTableColumns tableColumns = ctTable.getTableColumns();
|
||||
tableColumns.removeTableColumn(columnIndex);
|
||||
tableColumns.setCount(tableColumns.getTableColumnList().size());
|
||||
updateReferences();
|
||||
updateHeaders();
|
||||
}
|
||||
|
||||
|
@ -323,20 +435,25 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
|||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getColumnCount()} instead.
|
||||
*
|
||||
* @return the number of mapped table columns (see Open Office XML Part 4: chapter 3.5.1.4)
|
||||
*/
|
||||
@Deprecated
|
||||
@Removal(version = "4.2.0")
|
||||
public long getNumberOfMappedColumns() {
|
||||
return ctTable.getTableColumns().getCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The reference for the cells of the table
|
||||
* (see Open Office XML Part 4: chapter 3.5.1.2, attribute ref)
|
||||
* Get the area reference for the cells which this table covers. The area
|
||||
* includes header rows and totals rows.
|
||||
*
|
||||
* Does not track updates to underlying changes to CTTable
|
||||
* To synchronize with changes to the underlying CTTable,
|
||||
* call {@link #updateReferences()}.
|
||||
* Does not track updates to underlying changes to CTTable To synchronize
|
||||
* with changes to the underlying CTTable, call {@link #updateReferences()}.
|
||||
*
|
||||
* @return the area of the table
|
||||
* @see "Open Office XML Part 4: chapter 3.5.1.2, attribute ref"
|
||||
* @since 3.17 beta 1
|
||||
*/
|
||||
public AreaReference getCellReferences() {
|
||||
|
@ -346,16 +463,35 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
|||
SpreadsheetVersion.EXCEL2007
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the reference for the cells of the table
|
||||
* (see Open Office XML Part 4: chapter 3.5.1.2, attribute ref)
|
||||
* and synchronizes any changes
|
||||
* @param refs table range
|
||||
* Set the area reference for the cells which this table covers. The area
|
||||
* includes includes header rows and totals rows. Automatically synchronizes
|
||||
* any changes by calling {@link #updateHeaders()}.
|
||||
*
|
||||
* Note: The area's width should be identical to the amount of columns in
|
||||
* the table or the table may be invalid. All header rows, totals rows and
|
||||
* at least one data row must fit inside the area. Updating the area with
|
||||
* this method does not create or remove any columns and does not change any
|
||||
* cell values.
|
||||
*
|
||||
* @deprecated Use {@link #setTableArea} instead, which will ensure that the
|
||||
* the amount of columns always matches table area always width.
|
||||
*
|
||||
* @see "Open Office XML Part 4: chapter 3.5.1.2, attribute ref"
|
||||
* @since 3.17 beta 1
|
||||
*/
|
||||
@Deprecated
|
||||
@Removal(version="4.2.0")
|
||||
public void setCellReferences(AreaReference refs) {
|
||||
// Strip the Sheet name
|
||||
setCellRef(refs);
|
||||
}
|
||||
|
||||
@Internal
|
||||
protected void setCellRef(AreaReference refs) {
|
||||
|
||||
// Strip the sheet name,
|
||||
// CTWorksheet.getTableParts defines in which sheet the table is
|
||||
String ref = refs.formatAsString();
|
||||
if (ref.indexOf('!') != -1) {
|
||||
ref = ref.substring(ref.indexOf('!')+1);
|
||||
|
@ -383,6 +519,87 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
|||
updateHeaders();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the area reference for the cells which this table covers. The area
|
||||
* includes includes header rows and totals rows.
|
||||
*
|
||||
* Updating the area with this method will create new column as necessary to
|
||||
* the right side of the table but will not modify any cell values.
|
||||
*
|
||||
* @param refs
|
||||
* the new area of the table
|
||||
* @throws IllegalArgumentException
|
||||
* if the area is {@code null} or not
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public void setArea(AreaReference tableArea) {
|
||||
|
||||
if (tableArea == null) {
|
||||
throw new IllegalArgumentException("AreaReference must not be null");
|
||||
}
|
||||
|
||||
String areaSheetName = tableArea.getFirstCell().getSheetName();
|
||||
if (areaSheetName != null && !areaSheetName.equals(getXSSFSheet().getSheetName())) {
|
||||
// TODO to move a table from one sheet to another
|
||||
// CTWorksheet.getTableParts needs to be updated on both sheets
|
||||
throw new IllegalArgumentException(
|
||||
"The AreaReference must not reference a different sheet");
|
||||
}
|
||||
|
||||
int rowCount = (tableArea.getLastCell().getRow() - tableArea.getFirstCell().getRow()) + 1;
|
||||
int minimumRowCount = 1 + getHeaderRowCount() + getTotalsRowCount();
|
||||
if (rowCount < minimumRowCount) {
|
||||
throw new IllegalArgumentException("AreaReference needs at least " + minimumRowCount
|
||||
+ " rows, to cover at least one data row and all header rows and totals rows");
|
||||
}
|
||||
|
||||
// Strip the sheet name,
|
||||
// CTWorksheet.getTableParts defines in which sheet the table is
|
||||
String ref = tableArea.formatAsString();
|
||||
if (ref.indexOf('!') != -1) {
|
||||
ref = ref.substring(ref.indexOf('!') + 1);
|
||||
}
|
||||
|
||||
// Update
|
||||
ctTable.setRef(ref);
|
||||
if (ctTable.isSetAutoFilter()) {
|
||||
ctTable.getAutoFilter().setRef(ref);
|
||||
}
|
||||
updateReferences();
|
||||
|
||||
// add or remove columns on the right side of the table
|
||||
int columnCount = getColumnCount();
|
||||
int newColumnCount = (tableArea.getLastCell().getCol() - tableArea.getFirstCell().getCol()) + 1;
|
||||
if (newColumnCount > columnCount) {
|
||||
for (int i = columnCount; i < newColumnCount; i++) {
|
||||
createColumn(null, i);
|
||||
}
|
||||
} else if (newColumnCount < columnCount) {
|
||||
for (int i = columnCount; i > newColumnCount; i--) {
|
||||
removeColumn(i -1);
|
||||
}
|
||||
}
|
||||
|
||||
updateHeaders();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the area that this table covers.
|
||||
*
|
||||
* @return the table's area or {@code null} if the area has not been
|
||||
* initialized
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public AreaReference getArea() {
|
||||
String ref = ctTable.getRef();
|
||||
if (ref != null) {
|
||||
SpreadsheetVersion version = getXSSFSheet().getWorkbook().getSpreadsheetVersion();
|
||||
return new AreaReference(ctTable.getRef(), version);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The reference for the cell in the top-left part of the table
|
||||
* (see Open Office XML Part 4: chapter 3.5.1.2, attribute ref)
|
||||
|
@ -445,12 +662,17 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
|||
|
||||
|
||||
/**
|
||||
* @return the total number of rows in the selection. (Note: in this version autofiltering is ignored)
|
||||
* Get the total number of rows in this table, including all
|
||||
* {@linkplain #getHeaderRowCount() header rows} and all
|
||||
* {@linkplain #getTotalsRowCount() totals rows}. (Note: in this version
|
||||
* autofiltering is ignored)
|
||||
*
|
||||
* Returns <code>0</code> if the start or end cell references are not set.
|
||||
*
|
||||
* Does not track updates to underlying changes to CTTable
|
||||
* To synchronize with changes to the underlying CTTable,
|
||||
* call {@link #updateReferences()}.
|
||||
* Does not track updates to underlying changes to CTTable To synchronize
|
||||
* with changes to the underlying CTTable, call {@link #updateReferences()}.
|
||||
*
|
||||
* @return the total number of rows
|
||||
*/
|
||||
public int getRowCount() {
|
||||
CellReference from = getStartCellReference();
|
||||
|
@ -463,6 +685,117 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
|||
return rowCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of data rows in this table. This does not include any
|
||||
* header rows or totals rows.
|
||||
*
|
||||
* Returns <code>0</code> if the start or end cell references are not set.
|
||||
*
|
||||
* Does not track updates to underlying changes to CTTable To synchronize
|
||||
* with changes to the underlying CTTable, call {@link #updateReferences()}.
|
||||
*
|
||||
* @return the number of data rows
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public int getDataRowCount() {
|
||||
CellReference from = getStartCellReference();
|
||||
CellReference to = getEndCellReference();
|
||||
|
||||
int rowCount = 0;
|
||||
if (from != null && to != null) {
|
||||
rowCount = (to.getRow() - from.getRow() + 1) - getHeaderRowCount()
|
||||
- getTotalsRowCount();
|
||||
}
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of rows in the data area of the table. This does not
|
||||
* affect any header rows or totals rows.
|
||||
*
|
||||
* If the new row count is less than the current row count, superfluous rows
|
||||
* will be cleared. If the new row count is greater than the current row
|
||||
* count, cells below the table will be overwritten by the table.
|
||||
*
|
||||
* To resize the table without overwriting cells, use
|
||||
* {@link #setArea(AreaReference)} instead.
|
||||
*
|
||||
* @param newDataRowCount
|
||||
* new row count for the table
|
||||
* @throws IllegalArgumentException
|
||||
* if the row count is less than 1
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public void setDataRowCount(int newDataRowCount) {
|
||||
|
||||
if (newDataRowCount < 1) {
|
||||
throw new IllegalArgumentException("Table must have at least one data row");
|
||||
}
|
||||
|
||||
updateReferences();
|
||||
int dataRowCount = getDataRowCount();
|
||||
if (dataRowCount == newDataRowCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
CellReference tableStart = getStartCellReference();
|
||||
CellReference tableEnd = getEndCellReference();
|
||||
SpreadsheetVersion version = getXSSFSheet().getWorkbook().getSpreadsheetVersion();
|
||||
|
||||
// calculate new area
|
||||
int newTotalRowCount = getHeaderRowCount() + newDataRowCount + getTotalsRowCount();
|
||||
CellReference newTableEnd = new CellReference(tableStart.getRow() + newTotalRowCount - 1,
|
||||
tableEnd.getCol());
|
||||
AreaReference newTableArea = new AreaReference(tableStart, newTableEnd, version);
|
||||
|
||||
// clear cells
|
||||
CellReference clearAreaStart;
|
||||
CellReference clearAreaEnd;
|
||||
if (newDataRowCount < dataRowCount) {
|
||||
// table size reduced -
|
||||
// clear all table cells that are outside of the new area
|
||||
clearAreaStart = new CellReference(newTableArea.getLastCell().getRow() + 1,
|
||||
newTableArea.getFirstCell().getCol());
|
||||
clearAreaEnd = tableEnd;
|
||||
} else {
|
||||
// table size increased -
|
||||
// clear all cells below the table that are inside the new area
|
||||
clearAreaStart = new CellReference(tableEnd.getRow() + 1,
|
||||
newTableArea.getFirstCell().getCol());
|
||||
clearAreaEnd = newTableEnd;
|
||||
}
|
||||
AreaReference areaToClear = new AreaReference(clearAreaStart, clearAreaEnd, version);
|
||||
for (CellReference cellRef : areaToClear.getAllReferencedCells()) {
|
||||
XSSFRow row = getXSSFSheet().getRow(cellRef.getRow());
|
||||
if (row != null) {
|
||||
XSSFCell cell = row.getCell(cellRef.getCol());
|
||||
if (cell != null) {
|
||||
cell.setCellType(CellType.BLANK);
|
||||
cell.setCellStyle(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update table area
|
||||
setCellRef(newTableArea);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total number of columns in this table.
|
||||
*
|
||||
* @return the column count
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
CTTableColumns tableColumns = ctTable.getTableColumns();
|
||||
if(tableColumns == null) {
|
||||
return 0;
|
||||
}
|
||||
// Casting to int should be safe here - tables larger than the
|
||||
// sheet (which holds the actual data of the table) can't exists.
|
||||
return (int) tableColumns.getCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronize table headers with cell values in the parent sheet.
|
||||
* Headers <em>must</em> be in sync, otherwise Excel will display a
|
||||
|
@ -488,19 +821,22 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
|||
|
||||
if (row != null && row.getCTRow().validate()) {
|
||||
int cellnum = firstHeaderColumn;
|
||||
for (CTTableColumn col : getCTTable().getTableColumns().getTableColumnList()) {
|
||||
CTTableColumns ctTableColumns = getCTTable().getTableColumns();
|
||||
if(ctTableColumns != null) {
|
||||
for (CTTableColumn col : ctTableColumns.getTableColumnList()) {
|
||||
XSSFCell cell = row.getCell(cellnum);
|
||||
if (cell != null) {
|
||||
col.setName(formatter.formatCellValue(cell));
|
||||
}
|
||||
cellnum++;
|
||||
}
|
||||
ctColumns = null;
|
||||
columnMap = null;
|
||||
xmlColumnPr = null;
|
||||
commonXPath = null;
|
||||
}
|
||||
}
|
||||
tableColumns = null;
|
||||
columnMap = null;
|
||||
xmlColumnPrs = null;
|
||||
commonXPath = null;
|
||||
}
|
||||
|
||||
private static String caseInsensitive(String s) {
|
||||
return s.toUpperCase(Locale.ROOT);
|
||||
|
@ -522,11 +858,11 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
|||
if (columnHeader == null) return -1;
|
||||
if (columnMap == null) {
|
||||
// FIXME: replace with org.apache.commons.collections.map.CaseInsensitiveMap
|
||||
final int count = getTableColumns().length;
|
||||
final int count = getColumnCount();
|
||||
columnMap = new HashMap<>(count * 3 / 2);
|
||||
|
||||
int i = 0;
|
||||
for (CTTableColumn column : getTableColumns()) {
|
||||
for (XSSFTableColumn column : getColumns()) {
|
||||
String columnName = column.getName();
|
||||
columnMap.put(caseInsensitive(columnName), i);
|
||||
i++;
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/* ====================================================================
|
||||
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.xssf.usermodel;
|
||||
|
||||
import org.apache.poi.util.Internal;
|
||||
import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXmlColumnPr;
|
||||
|
||||
/**
|
||||
* A table column of an {@link XSSFTable}. Use {@link XSSFTable#createColumn} to
|
||||
* create new table columns.
|
||||
*
|
||||
* @author Leonard Kappe
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class XSSFTableColumn {
|
||||
|
||||
private final XSSFTable table;
|
||||
private final CTTableColumn ctTableColumn;
|
||||
private XSSFXmlColumnPr xmlColumnPr;
|
||||
|
||||
/**
|
||||
* Create a new table column.
|
||||
*
|
||||
* @param table
|
||||
* the table which contains the column
|
||||
* @param ctTableColumn
|
||||
* the table column xmlbean to wrap
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@Internal
|
||||
protected XSSFTableColumn(XSSFTable table, CTTableColumn ctTableColumn) {
|
||||
this.table = table;
|
||||
this.ctTableColumn = ctTableColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the table which contains this column
|
||||
*
|
||||
* @return the table containing this column
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public XSSFTable getTable() {
|
||||
return table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the identifier of this column, which is is unique per table.
|
||||
*
|
||||
* @return the column id
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public long getId() {
|
||||
return ctTableColumn.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the identifier of this column, which must be unique per table.
|
||||
*
|
||||
* It is up to the caller to enforce the uniqueness of the id.
|
||||
*
|
||||
* @return the column id
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public void setId(long columnId) {
|
||||
ctTableColumn.setId(columnId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the column, which is is unique per table.
|
||||
*
|
||||
* @return the column name
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public String getName() {
|
||||
return ctTableColumn.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the column, which is is unique per table.
|
||||
*
|
||||
* @return the column name
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public void setName(String columnName) {
|
||||
ctTableColumn.setName(columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the XmlColumnPr (XML column properties) if this column has an XML
|
||||
* mapping.
|
||||
*
|
||||
* @return the XmlColumnPr or <code>null</code> if this column has no XML
|
||||
* mapping
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public XSSFXmlColumnPr getXmlColumnPr() {
|
||||
if (xmlColumnPr == null) {
|
||||
CTXmlColumnPr ctXmlColumnPr = ctTableColumn.getXmlColumnPr();
|
||||
if (ctXmlColumnPr != null) {
|
||||
xmlColumnPr = new XSSFXmlColumnPr(this, ctXmlColumnPr);
|
||||
}
|
||||
}
|
||||
return xmlColumnPr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the column's position in its table, staring with zero from left to
|
||||
* right.
|
||||
*
|
||||
* @return the column index
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public int getColumnIndex() {
|
||||
return table.findColumnIndex(getName());
|
||||
}
|
||||
|
||||
}
|
|
@ -17,12 +17,14 @@
|
|||
|
||||
package org.apache.poi.xssf.usermodel.helpers;
|
||||
|
||||
import org.apache.poi.util.Internal;
|
||||
import org.apache.poi.util.Removal;
|
||||
import org.apache.poi.xssf.usermodel.XSSFTable;
|
||||
import org.apache.poi.xssf.usermodel.XSSFTableColumn;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXmlColumnPr;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXmlDataType.Enum;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* This class is a wrapper around the CTXmlColumnPr (Open Office XML Part 4:
|
||||
|
@ -34,15 +36,43 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXmlDataType.Enum;
|
|||
public class XSSFXmlColumnPr {
|
||||
|
||||
private XSSFTable table;
|
||||
private CTTableColumn ctTableColumn;
|
||||
private XSSFTableColumn tableColumn;
|
||||
private CTXmlColumnPr ctXmlColumnPr;
|
||||
|
||||
/**
|
||||
* Create a new XSSFXmlColumnPr (XML column properties) wrapper around a
|
||||
* CTXmlColumnPr.
|
||||
*
|
||||
* @param tableColumn
|
||||
* table column for which the XML column properties are set
|
||||
* @param ctXmlColumnPr
|
||||
* the XML column properties xmlbean to wrap
|
||||
*/
|
||||
@Internal
|
||||
public XSSFXmlColumnPr(XSSFTableColumn tableColumn, CTXmlColumnPr ctXmlColumnPr) {
|
||||
this.table = tableColumn.getTable();
|
||||
this.tableColumn = tableColumn;
|
||||
this.ctXmlColumnPr = ctXmlColumnPr;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Removal(version="4.2")
|
||||
public XSSFXmlColumnPr(XSSFTable table, CTTableColumn ctTableColum, CTXmlColumnPr ctXmlColumnPr) {
|
||||
this.table = table;
|
||||
this.ctTableColumn = ctTableColum;
|
||||
this.tableColumn = table.getColumns().get(table.findColumnIndex(ctTableColum.getName()));
|
||||
this.ctXmlColumnPr = ctXmlColumnPr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the column for which these XML column properties are set.
|
||||
*
|
||||
* @return the table column
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public XSSFTableColumn getTableColumn() {
|
||||
return tableColumn;
|
||||
}
|
||||
|
||||
public long getMapId() {
|
||||
return ctXmlColumnPr.getMapId();
|
||||
}
|
||||
|
@ -50,15 +80,20 @@ public class XSSFXmlColumnPr {
|
|||
public String getXPath() {
|
||||
return ctXmlColumnPr.getXpath();
|
||||
}
|
||||
|
||||
/**
|
||||
* (see Open Office XML Part 4: chapter 3.5.1.3)
|
||||
*
|
||||
* @deprecated Use {@link XSSFTableColumn#getId()} instead.
|
||||
*
|
||||
* @return An integer representing the unique identifier of this column.
|
||||
*/
|
||||
@Deprecated
|
||||
@Removal(version="4.2")
|
||||
public long getId() {
|
||||
return ctTableColumn.getId();
|
||||
return tableColumn.getId();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the XPath is, for example, /Node1/Node2/Node3 and /Node1/Node2 is the common XPath for the table, the local XPath is /Node3
|
||||
*
|
||||
|
@ -80,8 +115,4 @@ public class XSSFXmlColumnPr {
|
|||
return ctXmlColumnPr.getXmlDataType();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.util.Locale;
|
|||
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
|
||||
import org.apache.poi.ss.usermodel.CellType;
|
||||
import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||
import org.apache.poi.xssf.usermodel.XSSFMap;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||
|
@ -99,8 +100,9 @@ public class TestXSSFImportFromXML {
|
|||
"<ns1:Schema ID=\"" + cellC8 + "\" SchemaRef=\"c\" />" +
|
||||
"<ns1:Schema ID=\"" + cellC9 + "\" SchemaRef=\"d\" />");
|
||||
|
||||
for (int i = 10; i < 10010; i++) {
|
||||
testXML.append("<ns1:Schema ID=\"c").append(i).append("\" SchemaRef=\"d\" />");
|
||||
int cellOffset = 10; // cell C10
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
testXML.append("<ns1:Schema ID=\"c").append(i + cellOffset).append("\" SchemaRef=\"d\" />");
|
||||
}
|
||||
|
||||
testXML.append("<ns1:Map ID=\"1\" Name=\"\" RootElement=\"\" SchemaID=\"\" ShowImportExportValidationErrors=\"\" AutoFit=\"\" Append=\"\" PreserveSortAFLayout=\"\" PreserveFormat=\"\">" + "<ns1:DataBinding DataBindingLoadMode=\"\" />" + "</ns1:Map>" + "<ns1:Map ID=\"2\" Name=\"\" RootElement=\"\" SchemaID=\"\" ShowImportExportValidationErrors=\"\" AutoFit=\"\" Append=\"\" PreserveSortAFLayout=\"\" PreserveFormat=\"\">" + "<ns1:DataBinding DataBindingLoadMode=\"\" />" + "</ns1:Map>" + "<ns1:Map ID=\"3\" Name=\"\" RootElement=\"\" SchemaID=\"\" ShowImportExportValidationErrors=\"\" AutoFit=\"\" Append=\"\" PreserveSortAFLayout=\"\" PreserveFormat=\"\">" + "<ns1:DataBinding DataBindingLoadMode=\"\" />" + "</ns1:Map>" + "</ns1:MapInfo>\u0000");
|
||||
|
@ -114,6 +116,17 @@ public class TestXSSFImportFromXML {
|
|||
//Check for Schema element
|
||||
XSSFSheet sheet = wb.getSheetAt(1);
|
||||
|
||||
|
||||
// check table size (+1 for the header row)
|
||||
assertEquals(3 + 1, wb.getTable("Tabella1").getRowCount());
|
||||
assertEquals(10004 + 1, wb.getTable("Tabella2").getRowCount());
|
||||
|
||||
// table1 size was reduced, check that former table cells have been cleared
|
||||
assertEquals(CellType.BLANK, wb.getSheetAt(0).getRow(8).getCell(5).getCellType());
|
||||
|
||||
// table2 size was increased, check that new table cells have been cleared
|
||||
assertEquals(CellType.BLANK, sheet.getRow(10).getCell(3).getCellType());
|
||||
|
||||
assertEquals(cellC6, sheet.getRow(5).getCell(2).getStringCellValue());
|
||||
assertEquals(cellC7, sheet.getRow(6).getCell(2).getStringCellValue());
|
||||
assertEquals(cellC8, sheet.getRow(7).getCell(2).getStringCellValue());
|
||||
|
|
|
@ -31,6 +31,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.util.AreaReference;
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.util.TempFile;
|
||||
|
@ -223,6 +224,14 @@ public final class TestXSSFTable {
|
|||
wb.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getColumnCount() throws IOException {
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx");
|
||||
XSSFTable table = wb.getTable("\\_Prime.1");
|
||||
assertEquals(3, table.getColumnCount());
|
||||
wb.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAndSetDisplayName() throws IOException {
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx");
|
||||
|
@ -292,6 +301,130 @@ public final class TestXSSFTable {
|
|||
IOUtils.closeQuietly(wb);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDataRowCount() {
|
||||
XSSFWorkbook wb = new XSSFWorkbook();
|
||||
XSSFSheet sh = wb.createSheet();
|
||||
AreaReference tableArea = new AreaReference("B2:B6", wb.getSpreadsheetVersion());
|
||||
XSSFTable table = sh.createTable(tableArea);
|
||||
|
||||
assertEquals(5, table.getRowCount()); // includes column header
|
||||
assertEquals(4, table.getDataRowCount());
|
||||
|
||||
table.setArea(new AreaReference("B2:B7", wb.getSpreadsheetVersion()));
|
||||
|
||||
assertEquals(6, table.getRowCount());
|
||||
assertEquals(5, table.getDataRowCount());
|
||||
|
||||
IOUtils.closeQuietly(wb);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetDataRowCount() throws IOException {
|
||||
XSSFWorkbook wb = new XSSFWorkbook();
|
||||
XSSFSheet sh = wb.createSheet();
|
||||
|
||||
// 1 header row + 1 data row
|
||||
AreaReference tableArea = new AreaReference("C10:C11", wb.getSpreadsheetVersion());
|
||||
XSSFTable table = sh.createTable(tableArea);
|
||||
|
||||
assertEquals(2, table.getRowCount()); // includes all data and header/footer rows
|
||||
|
||||
assertEquals(1, table.getHeaderRowCount());
|
||||
assertEquals(1, table.getDataRowCount());
|
||||
assertEquals(0, table.getTotalsRowCount());
|
||||
|
||||
table.setDataRowCount(5);
|
||||
|
||||
assertEquals(6, table.getRowCount());
|
||||
|
||||
assertEquals(1, table.getHeaderRowCount());
|
||||
assertEquals(5, table.getDataRowCount());
|
||||
assertEquals(0, table.getTotalsRowCount());
|
||||
|
||||
assertEquals("C10:C15", table.getArea().formatAsString());
|
||||
|
||||
|
||||
IOUtils.closeQuietly(wb);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetArea() throws IOException {
|
||||
XSSFWorkbook wb = new XSSFWorkbook();
|
||||
XSSFSheet sh = wb.createSheet();
|
||||
|
||||
AreaReference tableArea = new AreaReference("B10:D12", wb.getSpreadsheetVersion());
|
||||
XSSFTable table = sh.createTable(tableArea);
|
||||
|
||||
assertEquals(3, table.getColumnCount());
|
||||
assertEquals(3, table.getRowCount());
|
||||
|
||||
// move table without resizing, shouldn't change row or column count
|
||||
AreaReference tableArea2 = new AreaReference("B11:D13", wb.getSpreadsheetVersion());
|
||||
table.setArea(tableArea2);
|
||||
|
||||
assertEquals(3, table.getColumnCount());
|
||||
assertEquals(3, table.getRowCount());
|
||||
|
||||
// increase size by 1 row and 1 column
|
||||
AreaReference tableArea3 = new AreaReference("B11:E14", wb.getSpreadsheetVersion());
|
||||
table.setArea(tableArea3);
|
||||
|
||||
assertEquals(4, table.getColumnCount());
|
||||
assertEquals(4, table.getRowCount());
|
||||
|
||||
// reduce size by 2 rows and 2 columns
|
||||
AreaReference tableArea4 = new AreaReference("C12:D13", wb.getSpreadsheetVersion());
|
||||
table.setArea(tableArea4);
|
||||
|
||||
assertEquals(2, table.getColumnCount());
|
||||
assertEquals(2, table.getRowCount());
|
||||
|
||||
IOUtils.closeQuietly(wb);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateColumn() {
|
||||
XSSFWorkbook wb = new XSSFWorkbook();
|
||||
XSSFSheet sh = wb.createSheet();
|
||||
|
||||
AreaReference tableArea = new AreaReference("A2:A3", wb.getSpreadsheetVersion());
|
||||
XSSFTable table = sh.createTable(tableArea);
|
||||
|
||||
assertEquals(1, table.getColumnCount());
|
||||
assertEquals(2, table.getRowCount());
|
||||
|
||||
// add columns
|
||||
table.createColumn("Column B");
|
||||
table.createColumn("Column D");
|
||||
table.createColumn("Column C", 2); // add between B and D
|
||||
table.updateReferences();
|
||||
table.updateHeaders();
|
||||
|
||||
assertEquals(4, table.getColumnCount());
|
||||
assertEquals(2, table.getRowCount());
|
||||
|
||||
assertEquals("Column 1", table.getColumns().get(0).getName()); // generated name
|
||||
assertEquals("Column B", table.getColumns().get(1).getName());
|
||||
assertEquals("Column C", table.getColumns().get(2).getName());
|
||||
assertEquals("Column D", table.getColumns().get(3).getName());
|
||||
|
||||
IOUtils.closeQuietly(wb);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateColumnInvalidIndex() throws IOException {
|
||||
try (XSSFWorkbook wb = new XSSFWorkbook();) {
|
||||
XSSFSheet sh = wb.createSheet();
|
||||
AreaReference tableArea = new AreaReference("D2:D3", wb.getSpreadsheetVersion());
|
||||
XSSFTable table = sh.createTable(tableArea);
|
||||
|
||||
// add columns
|
||||
table.createColumn("Column 2", 1);
|
||||
table.createColumn("Column 3", 3); // out of bounds
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDifferentHeaderTypes() throws IOException {
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("TablesWithDifferentHeaders.xlsx");
|
||||
|
@ -345,13 +478,13 @@ public final class TestXSSFTable {
|
|||
c5.setCellValue("CD");
|
||||
c6.setCellValue("EF");
|
||||
|
||||
// Setting up the CTTable
|
||||
XSSFTable t = s.createTable();
|
||||
// Setting up the table
|
||||
XSSFTable t = s.createTable(new AreaReference("A1:C3", wb.getSpreadsheetVersion()));
|
||||
t.setName("TableTest");
|
||||
t.setDisplayName("CT_Table_Test");
|
||||
t.addColumn();
|
||||
t.addColumn();
|
||||
t.addColumn();
|
||||
t.createColumn("Column 1");
|
||||
t.createColumn("Column 2");
|
||||
t.createColumn("Column 3");
|
||||
t.setCellReferences(wb.getCreationHelper().createAreaReference(
|
||||
new CellReference(c1), new CellReference(c6)
|
||||
));
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/* ====================================================================
|
||||
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.xssf.usermodel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||
import org.junit.Test;
|
||||
|
||||
public final class TestXSSFTableColumn {
|
||||
|
||||
@Test
|
||||
public void testGetColumnName() throws IOException {
|
||||
try (XSSFWorkbook wb = XSSFTestDataSamples
|
||||
.openSampleWorkbook("CustomXMLMappings-complex-type.xlsx")) {
|
||||
XSSFTable table = wb.getTable("Tabella2");
|
||||
|
||||
List<XSSFTableColumn> tableColumns = table.getColumns();
|
||||
|
||||
assertEquals("ID", tableColumns.get(0).getName());
|
||||
assertEquals("Unmapped Column", tableColumns.get(1).getName());
|
||||
assertEquals("SchemaRef", tableColumns.get(2).getName());
|
||||
assertEquals("Namespace", tableColumns.get(3).getName());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetColumnIndex() throws IOException {
|
||||
try (XSSFWorkbook wb = XSSFTestDataSamples
|
||||
.openSampleWorkbook("CustomXMLMappings-complex-type.xlsx")) {
|
||||
XSSFTable table = wb.getTable("Tabella2");
|
||||
|
||||
List<XSSFTableColumn> tableColumns = table.getColumns();
|
||||
|
||||
assertEquals(0, tableColumns.get(0).getColumnIndex());
|
||||
assertEquals(1, tableColumns.get(1).getColumnIndex());
|
||||
assertEquals(2, tableColumns.get(2).getColumnIndex());
|
||||
assertEquals(3, tableColumns.get(3).getColumnIndex());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetXmlColumnPrs() throws IOException {
|
||||
try (XSSFWorkbook wb = XSSFTestDataSamples
|
||||
.openSampleWorkbook("CustomXMLMappings-complex-type.xlsx")) {
|
||||
XSSFTable table = wb.getTable("Tabella2");
|
||||
|
||||
List<XSSFTableColumn> tableColumns = table.getColumns();
|
||||
|
||||
assertNotNull(tableColumns.get(0).getXmlColumnPr());
|
||||
assertNull(tableColumns.get(1).getXmlColumnPr()); // unmapped column
|
||||
assertNotNull(tableColumns.get(2).getColumnIndex());
|
||||
assertNotNull(tableColumns.get(3).getColumnIndex());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
Loading…
Reference in New Issue