git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1825315 13f79535-47bb-0310-9956-ffa450edef68pull/98/merge
@@ -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,35 +175,27 @@ 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++) { | |||
XSSFRow row = sheet.getRow(i); | |||
Node tableRootNode = getNodeByXPath(table.getCommonXpath(),doc.getFirstChild(),doc,true); | |||
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(); | |||
Node currentNode = getNodeByXPath(localXPath,tableRootNode,doc,false); | |||
mapCellOnNode(cell,currentNode); | |||
} | |||
XSSFXmlColumnPr xmlColumnPr = tableColumn.getXmlColumnPr(); | |||
if (xmlColumnPr != null) { | |||
String localXPath = xmlColumnPr.getLocalXPath(); | |||
Node currentNode = getNodeByXPath(localXPath,tableRootNode,doc,false); | |||
mapCellOnNode(cell, currentNode); | |||
} | |||
} | |||
} |
@@ -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,25 +125,32 @@ 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++) { | |||
// TODO: implement support for denormalized XMLs (see | |||
// OpenOffice part 4: chapter 3.5.1.7) | |||
Node singleNode = result.item(i).cloneNode(true); | |||
for (XSSFXmlColumnPr xmlColumnPr : table.getXmlColumnPrs()) { | |||
Node singleNode = result.item(i).cloneNode(true); | |||
for (XSSFTableColumn tableColum : table.getColumns()) { | |||
XSSFXmlColumnPr xmlColumnPr = tableColum.getXmlColumnPr(); | |||
if(xmlColumnPr == null) { | |||
continue; | |||
} | |||
int localColumnId = (int) xmlColumnPr.getId(); | |||
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); | |||
String value = (String) xpath.evaluate(localXPath, singleNode, XPathConstants.STRING); | |||
logger.log(POILogger.DEBUG, "Extracting with xpath " + localXPath + " : value is '" + value + "'"); | |||
XSSFRow row = table.getXSSFSheet().getRow(rowId); | |||
if (row == null) { | |||
@@ -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,10 +4058,28 @@ 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() { | |||
if(! worksheet.isSetTableParts()) { | |||
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; | |||
@@ -155,18 +158,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; | |||
} | |||
/** | |||
* | |||
@@ -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()); | |||
} | |||
// 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); | |||
} | |||
// Have the Headers updated if possible | |||
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(); | |||
@@ -462,6 +684,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. | |||
@@ -479,7 +812,7 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { | |||
public void updateHeaders() { | |||
XSSFSheet sheet = (XSSFSheet)getParent(); | |||
CellReference ref = getStartCellReference(); | |||
if(ref == null) return; | |||
if (ref == null) return; | |||
int headerRow = ref.getRow(); | |||
int firstHeaderColumn = ref.getCol(); | |||
@@ -488,18 +821,21 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { | |||
if (row != null && row.getCTRow().validate()) { | |||
int cellnum = firstHeaderColumn; | |||
for (CTTableColumn col : getCTTable().getTableColumns().getTableColumnList()) { | |||
XSSFCell cell = row.getCell(cellnum); | |||
if (cell != null) { | |||
col.setName(formatter.formatCellValue(cell)); | |||
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++; | |||
} | |||
cellnum++; | |||
} | |||
ctColumns = null; | |||
columnMap = null; | |||
xmlColumnPr = null; | |||
commonXPath = null; | |||
} | |||
tableColumns = null; | |||
columnMap = null; | |||
xmlColumnPrs = null; | |||
commonXPath = null; | |||
} | |||
private static String caseInsensitive(String s) { | |||
@@ -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: | |||
@@ -32,56 +34,85 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXmlDataType.Enum; | |||
* @author Roberto Manicardi | |||
*/ | |||
public class XSSFXmlColumnPr { | |||
private XSSFTable table; | |||
private CTTableColumn ctTableColumn; | |||
private CTXmlColumnPr ctXmlColumnPr; | |||
public XSSFXmlColumnPr(XSSFTable table ,CTTableColumn ctTableColum,CTXmlColumnPr ctXmlColumnPr){ | |||
this.table = table; | |||
this.ctTableColumn = ctTableColum; | |||
this.ctXmlColumnPr = ctXmlColumnPr; | |||
} | |||
public long getMapId(){ | |||
return ctXmlColumnPr.getMapId(); | |||
} | |||
public String getXPath(){ | |||
return ctXmlColumnPr.getXpath(); | |||
} | |||
/** | |||
* (see Open Office XML Part 4: chapter 3.5.1.3) | |||
* @return An integer representing the unique identifier of this column. | |||
*/ | |||
public long getId(){ | |||
return ctTableColumn.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 | |||
* | |||
* @return the local XPath | |||
*/ | |||
public String getLocalXPath(){ | |||
StringBuilder localXPath = new StringBuilder(); | |||
int numberOfCommonXPathAxis = table.getCommonXpath().split("/").length-1; | |||
String[] xPathTokens = ctXmlColumnPr.getXpath().split("/"); | |||
for(int i=numberOfCommonXPathAxis; i<xPathTokens.length;i++){ | |||
localXPath.append("/" +xPathTokens[i]); | |||
} | |||
return localXPath.toString(); | |||
} | |||
public Enum getXmlDataType() { | |||
return ctXmlColumnPr.getXmlDataType(); | |||
} | |||
private XSSFTable table; | |||
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.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(); | |||
} | |||
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 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 | |||
* | |||
* @return the local XPath | |||
*/ | |||
public String getLocalXPath() { | |||
StringBuilder localXPath = new StringBuilder(); | |||
int numberOfCommonXPathAxis = table.getCommonXpath().split("/").length-1; | |||
String[] xPathTokens = ctXmlColumnPr.getXpath().split("/"); | |||
for (int i = numberOfCommonXPathAxis; i < xPathTokens.length; i++) { | |||
localXPath.append("/" + xPathTokens[i]); | |||
} | |||
return localXPath.toString(); | |||
} | |||
public Enum getXmlDataType() { | |||
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; | |||
@@ -41,188 +42,200 @@ import org.junit.Test; | |||
import org.xml.sax.SAXException; | |||
public class TestXSSFImportFromXML { | |||
@Test | |||
public void testImportFromXML() throws IOException, XPathExpressionException, SAXException{ | |||
try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMappings.xlsx")) { | |||
String name = "name"; | |||
String teacher = "teacher"; | |||
String tutor = "tutor"; | |||
String cdl = "cdl"; | |||
String duration = "duration"; | |||
String topic = "topic"; | |||
String project = "project"; | |||
String credits = "credits"; | |||
String testXML = "<CORSO>" + | |||
"<NOME>" + name + "</NOME>" + | |||
"<DOCENTE>" + teacher + "</DOCENTE>" + | |||
"<TUTOR>" + tutor + "</TUTOR>" + | |||
"<CDL>" + cdl + "</CDL>" + | |||
"<DURATA>" + duration + "</DURATA>" + | |||
"<ARGOMENTO>" + topic + "</ARGOMENTO>" + | |||
"<PROGETTO>" + project + "</PROGETTO>" + | |||
"<CREDITI>" + credits + "</CREDITI>" + | |||
"</CORSO>\u0000"; | |||
XSSFMap map = wb.getMapInfo().getXSSFMapByName("CORSO_mapping"); | |||
assertNotNull(map); | |||
XSSFImportFromXML importer = new XSSFImportFromXML(map); | |||
importer.importFromXML(testXML); | |||
XSSFSheet sheet = wb.getSheetAt(0); | |||
XSSFRow row = sheet.getRow(0); | |||
assertTrue(row.getCell(0).getStringCellValue().equals(name)); | |||
assertTrue(row.getCell(1).getStringCellValue().equals(teacher)); | |||
assertTrue(row.getCell(2).getStringCellValue().equals(tutor)); | |||
assertTrue(row.getCell(3).getStringCellValue().equals(cdl)); | |||
assertTrue(row.getCell(4).getStringCellValue().equals(duration)); | |||
assertTrue(row.getCell(5).getStringCellValue().equals(topic)); | |||
assertTrue(row.getCell(6).getStringCellValue().equals(project)); | |||
assertTrue(row.getCell(7).getStringCellValue().equals(credits)); | |||
} | |||
} | |||
@Test(timeout=60000) | |||
public void testMultiTable() throws IOException, XPathExpressionException, SAXException{ | |||
try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMappings-complex-type.xlsx")) { | |||
String cellC6 = "c6"; | |||
String cellC7 = "c7"; | |||
String cellC8 = "c8"; | |||
String cellC9 = "c9"; | |||
StringBuilder testXML = new StringBuilder("<ns1:MapInfo xmlns:ns1=\"" + NS_SPREADSHEETML + "\" SelectionNamespaces=\"\">" + | |||
"<ns1:Schema ID=\"" + cellC6 + "\" SchemaRef=\"a\" />" + | |||
"<ns1:Schema ID=\"" + cellC7 + "\" SchemaRef=\"b\" />" + | |||
"<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\" />"); | |||
} | |||
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"); | |||
XSSFMap map = wb.getMapInfo().getXSSFMapByName("MapInfo_mapping"); | |||
assertNotNull(map); | |||
XSSFImportFromXML importer = new XSSFImportFromXML(map); | |||
importer.importFromXML(testXML.toString()); | |||
//Check for Schema element | |||
XSSFSheet sheet = wb.getSheetAt(1); | |||
assertEquals(cellC6, sheet.getRow(5).getCell(2).getStringCellValue()); | |||
assertEquals(cellC7, sheet.getRow(6).getCell(2).getStringCellValue()); | |||
assertEquals(cellC8, sheet.getRow(7).getCell(2).getStringCellValue()); | |||
assertEquals(cellC9, sheet.getRow(8).getCell(2).getStringCellValue()); | |||
assertEquals("c5001", sheet.getRow(5000).getCell(2).getStringCellValue()); | |||
} | |||
} | |||
@Test | |||
public void testSingleAttributeCellWithNamespace() throws IOException, XPathExpressionException, SAXException{ | |||
try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMapping-singleattributenamespace.xlsx")) { | |||
int id = 1; | |||
String displayName = "dispName"; | |||
String ref = "19"; | |||
int count = 21; | |||
String testXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>" + | |||
"<ns1:table xmlns:ns1=\"" + NS_SPREADSHEETML + "\" id=\"" + id + "\" displayName=\"" + displayName + "\" ref=\"" + ref + "\">" + | |||
"<ns1:tableColumns count=\"" + count + "\" />" + | |||
"</ns1:table>\u0000"; | |||
XSSFMap map = wb.getMapInfo().getXSSFMapByName("table_mapping"); | |||
assertNotNull(map); | |||
XSSFImportFromXML importer = new XSSFImportFromXML(map); | |||
importer.importFromXML(testXML); | |||
//Check for Schema element | |||
XSSFSheet sheet = wb.getSheetAt(0); | |||
assertEquals(new Double(id), sheet.getRow(28).getCell(1).getNumericCellValue(), 0); | |||
assertEquals(displayName, sheet.getRow(11).getCell(5).getStringCellValue()); | |||
assertEquals(ref, sheet.getRow(14).getCell(7).getStringCellValue()); | |||
assertEquals(new Double(count), sheet.getRow(18).getCell(3).getNumericCellValue(), 0); | |||
} | |||
} | |||
@Test | |||
public void testOptionalFields_Bugzilla_55864() throws IOException, XPathExpressionException, SAXException { | |||
try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55864.xlsx")) { | |||
String testXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + | |||
"<PersonInfoRoot>" + | |||
"<PersonData>" + | |||
"<FirstName>Albert</FirstName>" + | |||
"<LastName>Einstein</LastName>" + | |||
"<BirthDate>1879-03-14</BirthDate>" + | |||
"</PersonData>" + | |||
"</PersonInfoRoot>"; | |||
XSSFMap map = wb.getMapInfo().getXSSFMapByName("PersonInfoRoot_Map"); | |||
assertNotNull(map); | |||
XSSFImportFromXML importer = new XSSFImportFromXML(map); | |||
importer.importFromXML(testXML); | |||
XSSFSheet sheet = wb.getSheetAt(0); | |||
XSSFRow rowHeadings = sheet.getRow(0); | |||
XSSFRow rowData = sheet.getRow(1); | |||
assertEquals("FirstName", rowHeadings.getCell(0).getStringCellValue()); | |||
assertEquals("Albert", rowData.getCell(0).getStringCellValue()); | |||
assertEquals("LastName", rowHeadings.getCell(1).getStringCellValue()); | |||
assertEquals("Einstein", rowData.getCell(1).getStringCellValue()); | |||
assertEquals("BirthDate", rowHeadings.getCell(2).getStringCellValue()); | |||
assertEquals("1879-03-14", rowData.getCell(2).getStringCellValue()); | |||
// Value for OptionalRating is declared optional (minOccurs=0) in 55864.xlsx | |||
assertEquals("OptionalRating", rowHeadings.getCell(3).getStringCellValue()); | |||
assertNull("", rowData.getCell(3)); | |||
} | |||
} | |||
@Test | |||
public void testOptionalFields_Bugzilla_57890() throws IOException, ParseException, XPathExpressionException, SAXException { | |||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57890.xlsx"); | |||
String testXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + "<TestInfoRoot>" | |||
+ "<TestData>" + "<Int>" + Integer.MIN_VALUE + "</Int>" + "<UnsignedInt>12345</UnsignedInt>" | |||
+ "<double>1.0000123</double>" + "<Date>1991-03-14</Date>" + "</TestData>" + "</TestInfoRoot>"; | |||
XSSFMap map = wb.getMapInfo().getXSSFMapByName("TestInfoRoot_Map"); | |||
assertNotNull(map); | |||
XSSFImportFromXML importer = new XSSFImportFromXML(map); | |||
importer.importFromXML(testXML); | |||
XSSFSheet sheet = wb.getSheetAt(0); | |||
XSSFRow rowHeadings = sheet.getRow(0); | |||
XSSFRow rowData = sheet.getRow(1); | |||
assertEquals("Date", rowHeadings.getCell(0).getStringCellValue()); | |||
Date date = new SimpleDateFormat("yyyy-MM-dd", DateFormatSymbols.getInstance(Locale.ROOT)).parse("1991-3-14"); | |||
assertEquals(date, rowData.getCell(0).getDateCellValue()); | |||
assertEquals("Amount Int", rowHeadings.getCell(1).getStringCellValue()); | |||
assertEquals(new Double(Integer.MIN_VALUE), rowData.getCell(1).getNumericCellValue(), 0); | |||
assertEquals("Amount Double", rowHeadings.getCell(2).getStringCellValue()); | |||
assertEquals(1.0000123, rowData.getCell(2).getNumericCellValue(), 0); | |||
assertEquals("Amount UnsignedInt", rowHeadings.getCell(3).getStringCellValue()); | |||
assertEquals(new Double(12345), rowData.getCell(3).getNumericCellValue(), 0); | |||
wb.close(); | |||
} | |||
@Test | |||
public void testImportFromXML() throws IOException, XPathExpressionException, SAXException{ | |||
try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMappings.xlsx")) { | |||
String name = "name"; | |||
String teacher = "teacher"; | |||
String tutor = "tutor"; | |||
String cdl = "cdl"; | |||
String duration = "duration"; | |||
String topic = "topic"; | |||
String project = "project"; | |||
String credits = "credits"; | |||
String testXML = "<CORSO>" + | |||
"<NOME>" + name + "</NOME>" + | |||
"<DOCENTE>" + teacher + "</DOCENTE>" + | |||
"<TUTOR>" + tutor + "</TUTOR>" + | |||
"<CDL>" + cdl + "</CDL>" + | |||
"<DURATA>" + duration + "</DURATA>" + | |||
"<ARGOMENTO>" + topic + "</ARGOMENTO>" + | |||
"<PROGETTO>" + project + "</PROGETTO>" + | |||
"<CREDITI>" + credits + "</CREDITI>" + | |||
"</CORSO>\u0000"; | |||
XSSFMap map = wb.getMapInfo().getXSSFMapByName("CORSO_mapping"); | |||
assertNotNull(map); | |||
XSSFImportFromXML importer = new XSSFImportFromXML(map); | |||
importer.importFromXML(testXML); | |||
XSSFSheet sheet = wb.getSheetAt(0); | |||
XSSFRow row = sheet.getRow(0); | |||
assertTrue(row.getCell(0).getStringCellValue().equals(name)); | |||
assertTrue(row.getCell(1).getStringCellValue().equals(teacher)); | |||
assertTrue(row.getCell(2).getStringCellValue().equals(tutor)); | |||
assertTrue(row.getCell(3).getStringCellValue().equals(cdl)); | |||
assertTrue(row.getCell(4).getStringCellValue().equals(duration)); | |||
assertTrue(row.getCell(5).getStringCellValue().equals(topic)); | |||
assertTrue(row.getCell(6).getStringCellValue().equals(project)); | |||
assertTrue(row.getCell(7).getStringCellValue().equals(credits)); | |||
} | |||
} | |||
@Test(timeout=60000) | |||
public void testMultiTable() throws IOException, XPathExpressionException, SAXException{ | |||
try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMappings-complex-type.xlsx")) { | |||
String cellC6 = "c6"; | |||
String cellC7 = "c7"; | |||
String cellC8 = "c8"; | |||
String cellC9 = "c9"; | |||
StringBuilder testXML = new StringBuilder("<ns1:MapInfo xmlns:ns1=\"" + NS_SPREADSHEETML + "\" SelectionNamespaces=\"\">" + | |||
"<ns1:Schema ID=\"" + cellC6 + "\" SchemaRef=\"a\" />" + | |||
"<ns1:Schema ID=\"" + cellC7 + "\" SchemaRef=\"b\" />" + | |||
"<ns1:Schema ID=\"" + cellC8 + "\" SchemaRef=\"c\" />" + | |||
"<ns1:Schema ID=\"" + cellC9 + "\" 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"); | |||
XSSFMap map = wb.getMapInfo().getXSSFMapByName("MapInfo_mapping"); | |||
assertNotNull(map); | |||
XSSFImportFromXML importer = new XSSFImportFromXML(map); | |||
importer.importFromXML(testXML.toString()); | |||
//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()); | |||
assertEquals(cellC9, sheet.getRow(8).getCell(2).getStringCellValue()); | |||
assertEquals("c5001", sheet.getRow(5000).getCell(2).getStringCellValue()); | |||
} | |||
} | |||
@Test | |||
public void testSingleAttributeCellWithNamespace() throws IOException, XPathExpressionException, SAXException{ | |||
try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMapping-singleattributenamespace.xlsx")) { | |||
int id = 1; | |||
String displayName = "dispName"; | |||
String ref = "19"; | |||
int count = 21; | |||
String testXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>" + | |||
"<ns1:table xmlns:ns1=\"" + NS_SPREADSHEETML + "\" id=\"" + id + "\" displayName=\"" + displayName + "\" ref=\"" + ref + "\">" + | |||
"<ns1:tableColumns count=\"" + count + "\" />" + | |||
"</ns1:table>\u0000"; | |||
XSSFMap map = wb.getMapInfo().getXSSFMapByName("table_mapping"); | |||
assertNotNull(map); | |||
XSSFImportFromXML importer = new XSSFImportFromXML(map); | |||
importer.importFromXML(testXML); | |||
//Check for Schema element | |||
XSSFSheet sheet = wb.getSheetAt(0); | |||
assertEquals(new Double(id), sheet.getRow(28).getCell(1).getNumericCellValue(), 0); | |||
assertEquals(displayName, sheet.getRow(11).getCell(5).getStringCellValue()); | |||
assertEquals(ref, sheet.getRow(14).getCell(7).getStringCellValue()); | |||
assertEquals(new Double(count), sheet.getRow(18).getCell(3).getNumericCellValue(), 0); | |||
} | |||
} | |||
@Test | |||
public void testOptionalFields_Bugzilla_55864() throws IOException, XPathExpressionException, SAXException { | |||
try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55864.xlsx")) { | |||
String testXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + | |||
"<PersonInfoRoot>" + | |||
"<PersonData>" + | |||
"<FirstName>Albert</FirstName>" + | |||
"<LastName>Einstein</LastName>" + | |||
"<BirthDate>1879-03-14</BirthDate>" + | |||
"</PersonData>" + | |||
"</PersonInfoRoot>"; | |||
XSSFMap map = wb.getMapInfo().getXSSFMapByName("PersonInfoRoot_Map"); | |||
assertNotNull(map); | |||
XSSFImportFromXML importer = new XSSFImportFromXML(map); | |||
importer.importFromXML(testXML); | |||
XSSFSheet sheet = wb.getSheetAt(0); | |||
XSSFRow rowHeadings = sheet.getRow(0); | |||
XSSFRow rowData = sheet.getRow(1); | |||
assertEquals("FirstName", rowHeadings.getCell(0).getStringCellValue()); | |||
assertEquals("Albert", rowData.getCell(0).getStringCellValue()); | |||
assertEquals("LastName", rowHeadings.getCell(1).getStringCellValue()); | |||
assertEquals("Einstein", rowData.getCell(1).getStringCellValue()); | |||
assertEquals("BirthDate", rowHeadings.getCell(2).getStringCellValue()); | |||
assertEquals("1879-03-14", rowData.getCell(2).getStringCellValue()); | |||
// Value for OptionalRating is declared optional (minOccurs=0) in 55864.xlsx | |||
assertEquals("OptionalRating", rowHeadings.getCell(3).getStringCellValue()); | |||
assertNull("", rowData.getCell(3)); | |||
} | |||
} | |||
@Test | |||
public void testOptionalFields_Bugzilla_57890() throws IOException, ParseException, XPathExpressionException, SAXException { | |||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57890.xlsx"); | |||
String testXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + "<TestInfoRoot>" | |||
+ "<TestData>" + "<Int>" + Integer.MIN_VALUE + "</Int>" + "<UnsignedInt>12345</UnsignedInt>" | |||
+ "<double>1.0000123</double>" + "<Date>1991-03-14</Date>" + "</TestData>" + "</TestInfoRoot>"; | |||
XSSFMap map = wb.getMapInfo().getXSSFMapByName("TestInfoRoot_Map"); | |||
assertNotNull(map); | |||
XSSFImportFromXML importer = new XSSFImportFromXML(map); | |||
importer.importFromXML(testXML); | |||
XSSFSheet sheet = wb.getSheetAt(0); | |||
XSSFRow rowHeadings = sheet.getRow(0); | |||
XSSFRow rowData = sheet.getRow(1); | |||
assertEquals("Date", rowHeadings.getCell(0).getStringCellValue()); | |||
Date date = new SimpleDateFormat("yyyy-MM-dd", DateFormatSymbols.getInstance(Locale.ROOT)).parse("1991-3-14"); | |||
assertEquals(date, rowData.getCell(0).getDateCellValue()); | |||
assertEquals("Amount Int", rowHeadings.getCell(1).getStringCellValue()); | |||
assertEquals(new Double(Integer.MIN_VALUE), rowData.getCell(1).getNumericCellValue(), 0); | |||
assertEquals("Amount Double", rowHeadings.getCell(2).getStringCellValue()); | |||
assertEquals(1.0000123, rowData.getCell(2).getNumericCellValue(), 0); | |||
assertEquals("Amount UnsignedInt", rowHeadings.getCell(3).getStringCellValue()); | |||
assertEquals(new Double(12345), rowData.getCell(3).getNumericCellValue(), 0); | |||
wb.close(); | |||
} | |||
} |
@@ -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"); | |||
@@ -291,7 +300,131 @@ 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()); | |||
} | |||
} | |||
} |