git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1825315 13f79535-47bb-0310-9956-ffa450edef68tags/REL_4_0_0_FINAL
} | } | ||||
} | } | ||||
// Create the columns | // 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 | // Set which area the table should be placed in | ||||
AreaReference reference = wb.getCreationHelper().createAreaReference( | AreaReference reference = wb.getCreationHelper().createAreaReference( |
import org.apache.poi.xssf.usermodel.XSSFRow; | import org.apache.poi.xssf.usermodel.XSSFRow; | ||||
import org.apache.poi.xssf.usermodel.XSSFSheet; | import org.apache.poi.xssf.usermodel.XSSFSheet; | ||||
import org.apache.poi.xssf.usermodel.XSSFTable; | 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.XSSFSingleXmlCell; | ||||
import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr; | 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.Document; | ||||
import org.w3c.dom.Element; | import org.w3c.dom.Element; | ||||
import org.w3c.dom.NamedNodeMap; | import org.w3c.dom.NamedNodeMap; | ||||
// Exports elements and attributes mapped with tables | // Exports elements and attributes mapped with tables | ||||
if (table!=null) { | if (table!=null) { | ||||
List<CTTableColumn> tableColumns = table.getCTTable().getTableColumns().getTableColumnList(); | |||||
List<XSSFTableColumn> tableColumns = table.getColumns(); | |||||
XSSFSheet sheet = table.getXSSFSheet(); | 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(); | int endRow = table.getEndCellReference().getRow(); | ||||
for(int i = startRow; i<= endRow; i++) { | for(int i = startRow; i<= endRow; i++) { | ||||
XSSFRow row = sheet.getRow(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(); | 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) { | 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); | |||||
} | } | ||||
} | } | ||||
} | } |
import org.apache.poi.xssf.usermodel.XSSFMap; | import org.apache.poi.xssf.usermodel.XSSFMap; | ||||
import org.apache.poi.xssf.usermodel.XSSFRow; | import org.apache.poi.xssf.usermodel.XSSFRow; | ||||
import org.apache.poi.xssf.usermodel.XSSFTable; | 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.XSSFSingleXmlCell; | ||||
import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr; | import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr; | ||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXmlDataType; | import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXmlDataType; | ||||
String commonXPath = table.getCommonXpath(); | String commonXPath = table.getCommonXpath(); | ||||
NodeList result = (NodeList) xpath.evaluate(commonXPath, doc, XPathConstants.NODESET); | 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++) { | for (int i = 0; i < result.getLength(); i++) { | ||||
// TODO: implement support for denormalized XMLs (see | // TODO: implement support for denormalized XMLs (see | ||||
// OpenOffice part 4: chapter 3.5.1.7) | // 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 rowId = rowOffset + i; | ||||
int columnId = columnOffset + localColumnId; | |||||
int columnId = columnOffset + tableColum.getColumnIndex(); | |||||
String localXPath = xmlColumnPr.getLocalXPath(); | 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 | // 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 + "'"); | logger.log(POILogger.DEBUG, "Extracting with xpath " + localXPath + " : value is '" + value + "'"); | ||||
XSSFRow row = table.getXSSFSheet().getRow(rowId); | XSSFRow row = table.getXSSFSheet().getRow(rowId); | ||||
if (row == null) { | if (row == null) { | ||||
} | } | ||||
} | } | ||||
private static enum DataType { | private static enum DataType { | ||||
BOOLEAN(STXmlDataType.BOOLEAN), // | BOOLEAN(STXmlDataType.BOOLEAN), // | ||||
DOUBLE(STXmlDataType.DOUBLE), // | DOUBLE(STXmlDataType.DOUBLE), // |
import org.apache.poi.util.Internal; | import org.apache.poi.util.Internal; | ||||
import org.apache.poi.util.POILogFactory; | import org.apache.poi.util.POILogFactory; | ||||
import org.apache.poi.util.POILogger; | import org.apache.poi.util.POILogger; | ||||
import org.apache.poi.util.Removal; | |||||
import org.apache.poi.util.Units; | import org.apache.poi.util.Units; | ||||
import org.apache.poi.xssf.model.CommentsTable; | import org.apache.poi.xssf.model.CommentsTable; | ||||
import org.apache.poi.xssf.usermodel.XSSFPivotTable.PivotTableReferenceConfigurator; | import org.apache.poi.xssf.usermodel.XSSFPivotTable.PivotTableReferenceConfigurator; | ||||
} | } | ||||
/** | /** | ||||
* 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() { | 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(); | worksheet.addNewTableParts(); | ||||
} | } | ||||
tables.put(tbl.getId(), table); | tables.put(tbl.getId(), table); | ||||
if(tableArea != null) { | |||||
table.setArea(tableArea); | |||||
} | |||||
return table; | return table; | ||||
} | } | ||||
import java.io.OutputStream; | import java.io.OutputStream; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.Collections; | |||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Locale; | import java.util.Locale; | ||||
import org.apache.poi.openxml4j.opc.PackagePart; | import org.apache.poi.openxml4j.opc.PackagePart; | ||||
import org.apache.poi.ss.SpreadsheetVersion; | import org.apache.poi.ss.SpreadsheetVersion; | ||||
import org.apache.poi.ss.usermodel.Cell; | 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.DataFormatter; | ||||
import org.apache.poi.ss.usermodel.Table; | import org.apache.poi.ss.usermodel.Table; | ||||
import org.apache.poi.ss.usermodel.TableStyleInfo; | import org.apache.poi.ss.usermodel.TableStyleInfo; | ||||
import org.apache.poi.ss.util.AreaReference; | import org.apache.poi.ss.util.AreaReference; | ||||
import org.apache.poi.ss.util.CellReference; | import org.apache.poi.ss.util.CellReference; | ||||
import org.apache.poi.util.Internal; | import org.apache.poi.util.Internal; | ||||
import org.apache.poi.util.Removal; | |||||
import org.apache.poi.util.StringUtil; | import org.apache.poi.util.StringUtil; | ||||
import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr; | import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr; | ||||
import org.apache.xmlbeans.XmlException; | import org.apache.xmlbeans.XmlException; | ||||
/** | /** | ||||
* | * | ||||
* 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 | * @author Roberto Manicardi | ||||
public class XSSFTable extends POIXMLDocumentPart implements Table { | public class XSSFTable extends POIXMLDocumentPart implements Table { | ||||
private CTTable ctTable; | 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 HashMap<String, Integer> columnMap; | ||||
private transient CellReference startCellReference; | private transient CellReference startCellReference; | ||||
private transient CellReference endCellReference; | private transient CellReference endCellReference; | ||||
return false; | 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; | |||||
} | |||||
/** | /** | ||||
* | * | ||||
public String getCommonXpath() { | public String getCommonXpath() { | ||||
if (commonXPath == null) { | if (commonXPath == null) { | ||||
String[] commonTokens = {}; | String[] commonTokens = {}; | ||||
for (CTTableColumn column : getTableColumns()) { | |||||
for (XSSFTableColumn column : getColumns()) { | |||||
if (column.getXmlColumnPr()!=null) { | if (column.getXmlColumnPr()!=null) { | ||||
String xpath = column.getXmlColumnPr().getXpath(); | |||||
String xpath = column.getXmlColumnPr().getXPath(); | |||||
String[] tokens = xpath.split("/"); | String[] tokens = xpath.split("/"); | ||||
if (commonTokens.length==0) { | if (commonTokens.length==0) { | ||||
commonTokens = tokens; | commonTokens = tokens; | ||||
return commonXPath; | 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 | * 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} | * To clear the cache, call {@link #updateHeaders} | ||||
* | |||||
* @deprecated Use {@link XSSFTableColumn#getXmlColumnPr()} instead. | |||||
* | |||||
* @return List of XSSFXmlColumnPr | * @return List of XSSFXmlColumnPr | ||||
*/ | */ | ||||
@Deprecated | |||||
@Removal(version="4.2.0") | |||||
public List<XSSFXmlColumnPr> getXmlColumnPrs() { | 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 | // Ensure we have Table Columns | ||||
CTTableColumns columns = ctTable.getTableColumns(); | CTTableColumns columns = ctTable.getTableColumns(); | ||||
if (columns == null) { | if (columns == null) { | ||||
columns = ctTable.addNewTableColumns(); | 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(); | updateHeaders(); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* @deprecated Use {@link #getColumnCount()} instead. | |||||
* | |||||
* @return the number of mapped table columns (see Open Office XML Part 4: chapter 3.5.1.4) | * @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() { | public long getNumberOfMappedColumns() { | ||||
return ctTable.getTableColumns().getCount(); | 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 | * @since 3.17 beta 1 | ||||
*/ | */ | ||||
public AreaReference getCellReferences() { | public AreaReference getCellReferences() { | ||||
SpreadsheetVersion.EXCEL2007 | 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 | * @since 3.17 beta 1 | ||||
*/ | */ | ||||
@Deprecated | |||||
@Removal(version="4.2.0") | |||||
public void setCellReferences(AreaReference refs) { | 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(); | String ref = refs.formatAsString(); | ||||
if (ref.indexOf('!') != -1) { | if (ref.indexOf('!') != -1) { | ||||
ref = ref.substring(ref.indexOf('!')+1); | ref = ref.substring(ref.indexOf('!')+1); | ||||
updateHeaders(); | 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 | * @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) | * (see Open Office XML Part 4: chapter 3.5.1.2, attribute ref) | ||||
/** | /** | ||||
* @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. | * 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() { | public int getRowCount() { | ||||
CellReference from = getStartCellReference(); | CellReference from = getStartCellReference(); | ||||
} | } | ||||
return rowCount; | 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. | * Synchronize table headers with cell values in the parent sheet. | ||||
public void updateHeaders() { | public void updateHeaders() { | ||||
XSSFSheet sheet = (XSSFSheet)getParent(); | XSSFSheet sheet = (XSSFSheet)getParent(); | ||||
CellReference ref = getStartCellReference(); | CellReference ref = getStartCellReference(); | ||||
if(ref == null) return; | |||||
if (ref == null) return; | |||||
int headerRow = ref.getRow(); | int headerRow = ref.getRow(); | ||||
int firstHeaderColumn = ref.getCol(); | int firstHeaderColumn = ref.getCol(); | ||||
if (row != null && row.getCTRow().validate()) { | if (row != null && row.getCTRow().validate()) { | ||||
int cellnum = firstHeaderColumn; | 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) { | private static String caseInsensitive(String s) { | ||||
if (columnHeader == null) return -1; | if (columnHeader == null) return -1; | ||||
if (columnMap == null) { | if (columnMap == null) { | ||||
// FIXME: replace with org.apache.commons.collections.map.CaseInsensitiveMap | // FIXME: replace with org.apache.commons.collections.map.CaseInsensitiveMap | ||||
final int count = getTableColumns().length; | |||||
final int count = getColumnCount(); | |||||
columnMap = new HashMap<>(count * 3 / 2); | columnMap = new HashMap<>(count * 3 / 2); | ||||
int i = 0; | int i = 0; | ||||
for (CTTableColumn column : getTableColumns()) { | |||||
for (XSSFTableColumn column : getColumns()) { | |||||
String columnName = column.getName(); | String columnName = column.getName(); | ||||
columnMap.put(caseInsensitive(columnName), i); | columnMap.put(caseInsensitive(columnName), i); | ||||
i++; | i++; |
/* ==================================================================== | |||||
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()); | |||||
} | |||||
} |
package org.apache.poi.xssf.usermodel.helpers; | 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.XSSFTable; | ||||
import org.apache.poi.xssf.usermodel.XSSFTableColumn; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn; | import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn; | ||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXmlColumnPr; | import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXmlColumnPr; | ||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXmlDataType.Enum; | import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXmlDataType.Enum; | ||||
/** | /** | ||||
* | * | ||||
* This class is a wrapper around the CTXmlColumnPr (Open Office XML Part 4: | * This class is a wrapper around the CTXmlColumnPr (Open Office XML Part 4: | ||||
* @author Roberto Manicardi | * @author Roberto Manicardi | ||||
*/ | */ | ||||
public class XSSFXmlColumnPr { | 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(); | |||||
} | |||||
} | } |
import javax.xml.xpath.XPathExpressionException; | import javax.xml.xpath.XPathExpressionException; | ||||
import org.apache.poi.ss.usermodel.CellType; | |||||
import org.apache.poi.xssf.XSSFTestDataSamples; | import org.apache.poi.xssf.XSSFTestDataSamples; | ||||
import org.apache.poi.xssf.usermodel.XSSFMap; | import org.apache.poi.xssf.usermodel.XSSFMap; | ||||
import org.apache.poi.xssf.usermodel.XSSFRow; | import org.apache.poi.xssf.usermodel.XSSFRow; | ||||
import org.xml.sax.SAXException; | import org.xml.sax.SAXException; | ||||
public class TestXSSFImportFromXML { | 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(); | |||||
} | |||||
} | } |
import java.util.List; | import java.util.List; | ||||
import org.apache.poi.ss.usermodel.Cell; | 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.ss.util.CellReference; | ||||
import org.apache.poi.util.IOUtils; | import org.apache.poi.util.IOUtils; | ||||
import org.apache.poi.util.TempFile; | import org.apache.poi.util.TempFile; | ||||
wb.close(); | 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 | @Test | ||||
public void getAndSetDisplayName() throws IOException { | public void getAndSetDisplayName() throws IOException { | ||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); | XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); | ||||
IOUtils.closeQuietly(wb); | 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 | @Test | ||||
public void testDifferentHeaderTypes() throws IOException { | public void testDifferentHeaderTypes() throws IOException { | ||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("TablesWithDifferentHeaders.xlsx"); | XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("TablesWithDifferentHeaders.xlsx"); | ||||
c5.setCellValue("CD"); | c5.setCellValue("CD"); | ||||
c6.setCellValue("EF"); | 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.setName("TableTest"); | ||||
t.setDisplayName("CT_Table_Test"); | 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( | t.setCellReferences(wb.getCreationHelper().createAreaReference( | ||||
new CellReference(c1), new CellReference(c6) | new CellReference(c1), new CellReference(c6) | ||||
)); | )); |
/* ==================================================================== | |||||
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()); | |||||
} | |||||
} | |||||
} |