support for custom XML mappings in XSSF, see Bugzilla 47520
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@794539 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9424d59da3
commit
8a3095d0b6
@ -33,6 +33,7 @@
|
||||
|
||||
<changes>
|
||||
<release version="3.5-beta7" date="2009-??-??">
|
||||
<action dev="POI-DEVELOPERS" type="add">47520 - Initial support for custom XML mappings in XSSF</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">47460 - Fixed NPE when retrieving core properties from a newly created workbook</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">47498 - Fixed HyperlinkRecord to properly handle URL monikers</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">47504 - Fixed XSSFWorkbook to read files with hyperlinks to document locations</action>
|
||||
|
@ -0,0 +1,42 @@
|
||||
/* ====================================================================
|
||||
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.examples;
|
||||
|
||||
import org.apache.poi.xssf.extractor.XSSFExportToXml;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFMap;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* Print all custom XML mappings registered in the given workbook
|
||||
*/
|
||||
public class CustomXMLMapping {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
XSSFWorkbook wb = new XSSFWorkbook(args[0]);
|
||||
|
||||
for (XSSFMap map : wb.getCustomXMLMappings()) {
|
||||
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
exporter.exportToXML(os, true);
|
||||
String xml = os.toString("UTF-8");
|
||||
System.out.println(xml);
|
||||
}
|
||||
}
|
||||
}
|
544
src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java
Executable file
544
src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java
Executable file
@ -0,0 +1,544 @@
|
||||
/* ====================================================================
|
||||
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.extractor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import javax.xml.validation.Validator;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.xssf.model.Table;
|
||||
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.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.helpers.XSSFSingleXmlCell;
|
||||
import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXmlDataType;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Maps an XLSX to an XML according to one of the mapping defined.
|
||||
*
|
||||
*
|
||||
* The output XML Schema must respect this limitations:
|
||||
*
|
||||
* <ul>
|
||||
* <li> all mandatory elements and attributes must be mapped </li>
|
||||
*
|
||||
* <li> no <any> in complex type/element declaration </li>
|
||||
* <li> no <anyAttribute> attributes declaration </li>
|
||||
* <li> no recursive structures: recursive structures can't be nested more than one level </li>
|
||||
* <li> no abstract elements: abstract complex types can be declared but must not be used in elements. </li>
|
||||
* <li> no mixed content: an element can't contain simple text and child element(s) together </li>
|
||||
* <li> no <substitutionGroup> in complex type/element declaration </li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Roberto Manicardi
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
public class XSSFExportToXml implements Comparator<String>{
|
||||
|
||||
private XSSFMap map;
|
||||
|
||||
/**
|
||||
* Creates a new exporter and sets the mapping to be used when generating the XML output document
|
||||
*
|
||||
* @param map the mapping rule to be used
|
||||
*/
|
||||
public XSSFExportToXml(XSSFMap map){
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Exports the data in an XML stream
|
||||
*
|
||||
* @param os OutputStream in which will contain the output XML
|
||||
* @param validate if true, validates the XML againts the XML Schema
|
||||
* @throws SAXException
|
||||
*/
|
||||
public void exportToXML(OutputStream os, boolean validate) throws SAXException{
|
||||
exportToXML(os,"UTF-8", validate);
|
||||
}
|
||||
|
||||
private Document getEmptyDocument() throws ParserConfigurationException{
|
||||
|
||||
|
||||
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
|
||||
Document doc = docBuilder.newDocument();
|
||||
|
||||
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the data in an XML stream
|
||||
*
|
||||
* @param os OutputStream in which will contain the output XML
|
||||
* @param encoding the output charset encoding
|
||||
* @param validate if true, validates the XML againts the XML Schema
|
||||
* @throws SAXException
|
||||
* @throws InvalidFormatException
|
||||
*/
|
||||
|
||||
public void exportToXML(OutputStream os, String encoding, boolean validate) throws SAXException{
|
||||
List<XSSFSingleXmlCell> singleXMLCells = map.getRelatedSingleXMLCell();
|
||||
List<Table> tables = map.getRelatedTables();
|
||||
|
||||
String rootElement = map.getCtMap().getRootElement();
|
||||
|
||||
try{
|
||||
|
||||
Document doc = getEmptyDocument();
|
||||
|
||||
Element root = null;
|
||||
|
||||
if(isNamespaceDeclared()){
|
||||
root=doc.createElementNS(getNamespace(),rootElement);
|
||||
}else{
|
||||
root=doc.createElement(rootElement);
|
||||
}
|
||||
doc.appendChild(root);
|
||||
|
||||
|
||||
List<String> xpaths = new Vector<String>();
|
||||
Map<String,XSSFSingleXmlCell> singleXmlCellsMappings = new HashMap<String,XSSFSingleXmlCell>();
|
||||
Map<String,Table> tableMappings = new HashMap<String,Table>();
|
||||
|
||||
for(XSSFSingleXmlCell simpleXmlCell : singleXMLCells){
|
||||
xpaths.add(simpleXmlCell.getXpath());
|
||||
singleXmlCellsMappings.put(simpleXmlCell.getXpath(), simpleXmlCell);
|
||||
}
|
||||
for(Table table : tables){
|
||||
String commonXPath = table.getCommonXpath();
|
||||
xpaths.add(commonXPath);
|
||||
tableMappings.put(commonXPath, table);
|
||||
}
|
||||
|
||||
|
||||
Collections.sort(xpaths,this);
|
||||
|
||||
for(String xpath : xpaths){
|
||||
|
||||
XSSFSingleXmlCell simpleXmlCell = singleXmlCellsMappings.get(xpath);
|
||||
Table table = tableMappings.get(xpath);
|
||||
|
||||
if(!xpath.matches(".*\\[.*")){
|
||||
|
||||
// Exports elements and attributes mapped with simpleXmlCell
|
||||
if(simpleXmlCell!=null){
|
||||
XSSFCell cell = simpleXmlCell.getReferencedCell();
|
||||
if(cell!=null){
|
||||
Node currentNode = getNodeByXPath(xpath,doc.getFirstChild(),doc,false);
|
||||
STXmlDataType.Enum dataType = simpleXmlCell.getXmlDataType();
|
||||
mapCellOnNode(cell,currentNode,dataType);
|
||||
}
|
||||
}
|
||||
|
||||
// Exports elements and attributes mapped with tables
|
||||
if(table!=null){
|
||||
|
||||
List<XSSFXmlColumnPr> tableColumns = table.getXmlColumnPrs();
|
||||
|
||||
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 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);
|
||||
|
||||
short startColumnIndex = table.getStartCellReference().getCol();
|
||||
for(int j = startColumnIndex; j<= table.getEndCellReference().getCol();j++){
|
||||
XSSFCell cell = row.getCell(j);
|
||||
if(cell!=null){
|
||||
XSSFXmlColumnPr pointer = tableColumns.get(j-startColumnIndex);
|
||||
String localXPath = pointer.getLocalXPath();
|
||||
Node currentNode = getNodeByXPath(localXPath,tableRootNode,doc,false);
|
||||
STXmlDataType.Enum dataType = pointer.getXmlDataType();
|
||||
|
||||
|
||||
mapCellOnNode(cell,currentNode,dataType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}else{
|
||||
// TODO: implement filtering management in xpath
|
||||
}
|
||||
}
|
||||
|
||||
boolean isValid = true;
|
||||
if(validate){
|
||||
isValid =isValid(doc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(isValid){
|
||||
|
||||
/////////////////
|
||||
//Output the XML
|
||||
|
||||
//set up a transformer
|
||||
TransformerFactory transfac = TransformerFactory.newInstance();
|
||||
Transformer trans = transfac.newTransformer();
|
||||
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||
trans.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
trans.setOutputProperty(OutputKeys.ENCODING, encoding);
|
||||
|
||||
//create string from xml tree
|
||||
|
||||
StreamResult result = new StreamResult(os);
|
||||
DOMSource source = new DOMSource(doc);
|
||||
trans.transform(source, result);
|
||||
|
||||
}
|
||||
}catch(ParserConfigurationException e){
|
||||
e.printStackTrace();
|
||||
}catch(TransformerException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the generated XML against the XML Schema associated with the XSSFMap
|
||||
*
|
||||
* @param xml the XML to validate
|
||||
* @return
|
||||
*/
|
||||
|
||||
private boolean isValid(Document xml) throws SAXException{
|
||||
boolean isValid = false;
|
||||
try{
|
||||
String language = XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
||||
SchemaFactory factory = SchemaFactory.newInstance(language);
|
||||
|
||||
Source source = new DOMSource(map.getSchema());
|
||||
Schema schema = factory.newSchema(source);
|
||||
Validator validator = schema.newValidator();
|
||||
validator.validate(new DOMSource(xml));
|
||||
//if no exceptions where raised, the document is valid
|
||||
isValid=true;
|
||||
|
||||
|
||||
}catch(IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
|
||||
private void mapCellOnNode(XSSFCell cell, Node node, STXmlDataType.Enum outputDataType){
|
||||
|
||||
|
||||
String value ="";
|
||||
switch (cell.getCellType()){
|
||||
|
||||
case XSSFCell.CELL_TYPE_STRING: value = cell.getStringCellValue(); break;
|
||||
case XSSFCell.CELL_TYPE_BOOLEAN: value += cell.getBooleanCellValue(); break;
|
||||
case XSSFCell.CELL_TYPE_ERROR: value = cell.getErrorCellString();
|
||||
case XSSFCell.CELL_TYPE_FORMULA: value = cell.getStringCellValue(); break;
|
||||
case XSSFCell.CELL_TYPE_NUMERIC: value += cell.getRawValue(); break;
|
||||
default: ;
|
||||
|
||||
}
|
||||
if(node instanceof Element){
|
||||
Element currentElement = (Element) node;
|
||||
currentElement.setTextContent(value);
|
||||
}else{
|
||||
node.setNodeValue(value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private String removeNamespace(String elementName){
|
||||
return elementName.matches(".*:.*")?elementName.split(":")[1]:elementName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Node getNodeByXPath(String xpath,Node rootNode,Document doc,boolean createMultipleInstances){
|
||||
String[] xpathTokens = xpath.split("/");
|
||||
|
||||
|
||||
Node currentNode =rootNode;
|
||||
// The first token is empty, the second is the root node
|
||||
for(int i =2; i<xpathTokens.length;i++){
|
||||
|
||||
String axisName = removeNamespace(xpathTokens[i]);
|
||||
|
||||
|
||||
if(!axisName.startsWith("@")){
|
||||
|
||||
NodeList list =currentNode.getChildNodes();
|
||||
|
||||
Node selectedNode = null;
|
||||
if(!(createMultipleInstances && i==xpathTokens.length-1) ){
|
||||
// select the last child node only if we need to map to a single cell
|
||||
selectedNode = selectNode(axisName, list);
|
||||
}
|
||||
if(selectedNode==null){
|
||||
selectedNode = createElement(doc, currentNode, axisName);
|
||||
}
|
||||
currentNode = selectedNode;
|
||||
}else{
|
||||
|
||||
|
||||
Node attribute = createAttribute(doc, currentNode, axisName);
|
||||
|
||||
currentNode = attribute;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return currentNode;
|
||||
}
|
||||
|
||||
private Node createAttribute(Document doc, Node currentNode, String axisName) {
|
||||
String attributeName = axisName.substring(1);
|
||||
NamedNodeMap attributesMap = currentNode.getAttributes();
|
||||
Node attribute = attributesMap.getNamedItem(attributeName);
|
||||
if(attribute==null){
|
||||
attribute = doc.createAttribute(attributeName);
|
||||
attributesMap.setNamedItem(attribute);
|
||||
}
|
||||
return attribute;
|
||||
}
|
||||
|
||||
private Node createElement(Document doc, Node currentNode, String axisName) {
|
||||
Node selectedNode;
|
||||
if(isNamespaceDeclared()){
|
||||
selectedNode =doc.createElementNS(getNamespace(),axisName);
|
||||
}else{
|
||||
selectedNode =doc.createElement(axisName);
|
||||
}
|
||||
currentNode.appendChild(selectedNode);
|
||||
return selectedNode;
|
||||
}
|
||||
|
||||
private Node selectNode(String axisName, NodeList list) {
|
||||
Node selectedNode = null;
|
||||
for(int j=0;j<list.getLength();j++){
|
||||
Node node = list.item(j);
|
||||
if(node.getNodeName().equals(axisName)){
|
||||
selectedNode=node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return selectedNode;
|
||||
}
|
||||
|
||||
|
||||
private boolean isNamespaceDeclared(){
|
||||
String schemaNamespace = getNamespace();
|
||||
return schemaNamespace!=null && !schemaNamespace.equals("");
|
||||
}
|
||||
|
||||
private String getNamespace(){
|
||||
return map.getCTSchema().getNamespace();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compares two xpaths to define an ordering according to the XML Schema
|
||||
*
|
||||
*/
|
||||
public int compare(String leftXpath, String rightXpath) {
|
||||
|
||||
int result = 0;
|
||||
Node xmlSchema = map.getSchema();
|
||||
|
||||
|
||||
|
||||
|
||||
String[] leftTokens = leftXpath.split("/");
|
||||
String[] rightTokens = rightXpath.split("/");
|
||||
|
||||
int minLenght = leftTokens.length< rightTokens.length? leftTokens.length : rightTokens.length;
|
||||
|
||||
Node localComplexTypeRootNode = xmlSchema;
|
||||
|
||||
|
||||
for(int i =1;i <minLenght; i++){
|
||||
|
||||
String leftElementName =leftTokens[i];
|
||||
String rightElementName = rightTokens[i];
|
||||
|
||||
if(leftElementName.equals(rightElementName)){
|
||||
|
||||
|
||||
Node complexType = getComplexTypeForElement(leftElementName, xmlSchema,localComplexTypeRootNode);
|
||||
localComplexTypeRootNode = complexType;
|
||||
}else{
|
||||
int leftIndex = indexOfElementInComplexType(leftElementName,localComplexTypeRootNode);
|
||||
int rightIndex = indexOfElementInComplexType(rightElementName,localComplexTypeRootNode);
|
||||
if(leftIndex!=-1 && rightIndex!=-1){
|
||||
if( leftIndex < rightIndex){
|
||||
result = -1;
|
||||
}if( leftIndex > rightIndex){
|
||||
result = 1;
|
||||
}
|
||||
}else{
|
||||
// NOTE: the xpath doesn't match correctly in the schema
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private int indexOfElementInComplexType(String elementName,Node complexType){
|
||||
|
||||
NodeList list = complexType.getChildNodes();
|
||||
int indexOf = -1;
|
||||
|
||||
for(int i=0; i< list.getLength();i++){
|
||||
Node node = list.item(i);
|
||||
if(node instanceof Element){
|
||||
if(node.getLocalName().equals("element")){
|
||||
Node nameAttribute = node.getAttributes().getNamedItem("name");
|
||||
if(nameAttribute.getNodeValue().equals(removeNamespace(elementName))){
|
||||
indexOf = i;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return indexOf;
|
||||
|
||||
}
|
||||
|
||||
private Node getComplexTypeForElement(String elementName,Node xmlSchema,Node localComplexTypeRootNode){
|
||||
Node complexTypeNode = null;
|
||||
|
||||
String elementNameWithoutNamespace = removeNamespace(elementName);
|
||||
|
||||
|
||||
NodeList list = localComplexTypeRootNode.getChildNodes();
|
||||
String complexTypeName = "";
|
||||
|
||||
|
||||
|
||||
for(int i=0; i< list.getLength();i++){
|
||||
Node node = list.item(i);
|
||||
if( node instanceof Element){
|
||||
if(node.getLocalName().equals("element")){
|
||||
Node nameAttribute = node.getAttributes().getNamedItem("name");
|
||||
if(nameAttribute.getNodeValue().equals(elementNameWithoutNamespace)){
|
||||
Node complexTypeAttribute = node.getAttributes().getNamedItem("type");
|
||||
if(complexTypeAttribute!=null){
|
||||
complexTypeName = complexTypeAttribute.getNodeValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Note: we expect that all the complex types are defined at root level
|
||||
if(!complexTypeName.equals("")){
|
||||
NodeList complexTypeList = xmlSchema.getChildNodes();
|
||||
for(int i=0; i< complexTypeList.getLength();i++){
|
||||
Node node = list.item(i);
|
||||
if( node instanceof Element){
|
||||
if(node.getLocalName().equals("complexType")){
|
||||
Node nameAttribute = node.getAttributes().getNamedItem("name");
|
||||
if(nameAttribute.getNodeValue().equals(complexTypeName)){
|
||||
|
||||
NodeList complexTypeChildList =node.getChildNodes();
|
||||
for(int j=0; j<complexTypeChildList.getLength();j++){
|
||||
Node sequence = complexTypeChildList.item(j);
|
||||
|
||||
if( sequence instanceof Element){
|
||||
if(sequence.getLocalName().equals("sequence")){
|
||||
complexTypeNode = sequence;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(complexTypeNode!=null){
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return complexTypeNode;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
148
src/ooxml/java/org/apache/poi/xssf/model/MapInfo.java
Executable file
148
src/ooxml/java/org/apache/poi/xssf/model/MapInfo.java
Executable file
@ -0,0 +1,148 @@
|
||||
/* ====================================================================
|
||||
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.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.xssf.usermodel.XSSFMap;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMap;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMapInfo;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSchema;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.MapInfoDocument;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class implements the Custom XML Mapping Part (Open Office XML Part 1:
|
||||
* chapter 12.3.6)
|
||||
*
|
||||
* An instance of this part type contains a schema for an XML file, and
|
||||
* information on the behavior that is used when allowing this custom XML schema
|
||||
* to be mapped into the spreadsheet.
|
||||
*
|
||||
* @author Roberto Manicardi
|
||||
*/
|
||||
|
||||
public class MapInfo extends POIXMLDocumentPart {
|
||||
|
||||
private CTMapInfo mapInfo;
|
||||
|
||||
private Map<Integer, XSSFMap> maps ;
|
||||
|
||||
public MapInfo() {
|
||||
super();
|
||||
mapInfo = CTMapInfo.Factory.newInstance();
|
||||
|
||||
}
|
||||
|
||||
public MapInfo(PackagePart part, PackageRelationship rel)
|
||||
throws IOException {
|
||||
super(part, rel);
|
||||
readFrom(part.getInputStream());
|
||||
}
|
||||
|
||||
public void readFrom(InputStream is) throws IOException {
|
||||
try {
|
||||
MapInfoDocument doc = MapInfoDocument.Factory.parse(is);
|
||||
mapInfo = doc.getMapInfo();
|
||||
|
||||
maps= new HashMap<Integer, XSSFMap>();
|
||||
for(CTMap map :mapInfo.getMapArray()){
|
||||
maps.put((int)map.getID(), new XSSFMap(map,this));
|
||||
}
|
||||
|
||||
} catch (XmlException e) {
|
||||
throw new IOException(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent XSSFWorkbook
|
||||
*
|
||||
* @return the parent XSSFWorkbook
|
||||
*/
|
||||
public XSSFWorkbook getWorkbook() {
|
||||
return (XSSFWorkbook)getParent();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the internal data object
|
||||
*/
|
||||
public CTMapInfo getCTMapInfo(){
|
||||
return mapInfo;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the CTSchema buy it's ID
|
||||
* @param schemaId the schema ID
|
||||
* @return
|
||||
*/
|
||||
public CTSchema getCTSchemaById(String schemaId){
|
||||
CTSchema xmlSchema = null;
|
||||
|
||||
CTSchema[] schemas = mapInfo.getSchemaArray();
|
||||
for(CTSchema schema: schemas){
|
||||
if(schema.getID().equals(schemaId)){
|
||||
xmlSchema = schema;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return xmlSchema;
|
||||
}
|
||||
|
||||
|
||||
public XSSFMap getXSSFMapById(int id){
|
||||
return maps.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return all the mappings configured in this document
|
||||
*/
|
||||
public Collection<XSSFMap> getAllXSSFMaps(){
|
||||
return maps.values();
|
||||
}
|
||||
|
||||
protected void writeTo(OutputStream out) throws IOException {
|
||||
MapInfoDocument doc = MapInfoDocument.Factory.newInstance();
|
||||
doc.setMapInfo(mapInfo);
|
||||
doc.save(out, DEFAULT_XML_OPTIONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void commit() throws IOException {
|
||||
PackagePart part = getPackagePart();
|
||||
OutputStream out = part.getOutputStream();
|
||||
writeTo(out);
|
||||
out.close();
|
||||
}
|
||||
|
||||
}
|
106
src/ooxml/java/org/apache/poi/xssf/model/SingleXmlCells.java
Executable file
106
src/ooxml/java/org/apache/poi/xssf/model/SingleXmlCells.java
Executable file
@ -0,0 +1,106 @@
|
||||
/* ====================================================================
|
||||
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.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.helpers.XSSFSingleXmlCell;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSingleXmlCell;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSingleXmlCells;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.SingleXmlCellsDocument;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* This class implements the Single Cell Tables Part (Open Office XML Part 4:
|
||||
* chapter 3.5.2)
|
||||
*
|
||||
*
|
||||
* @author Roberto Manicardi
|
||||
*/
|
||||
public class SingleXmlCells extends POIXMLDocumentPart {
|
||||
|
||||
|
||||
private CTSingleXmlCells singleXMLCells;
|
||||
|
||||
public SingleXmlCells() {
|
||||
super();
|
||||
singleXMLCells = CTSingleXmlCells.Factory.newInstance();
|
||||
|
||||
}
|
||||
|
||||
public SingleXmlCells(PackagePart part, PackageRelationship rel)
|
||||
throws IOException {
|
||||
super(part, rel);
|
||||
readFrom(part.getInputStream());
|
||||
}
|
||||
|
||||
public void readFrom(InputStream is) throws IOException {
|
||||
try {
|
||||
SingleXmlCellsDocument doc = SingleXmlCellsDocument.Factory.parse(is);
|
||||
singleXMLCells = doc.getSingleXmlCells();
|
||||
} catch (XmlException e) {
|
||||
throw new IOException(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public XSSFSheet getXSSFSheet(){
|
||||
return (XSSFSheet) getParent();
|
||||
}
|
||||
|
||||
protected void writeTo(OutputStream out) throws IOException {
|
||||
SingleXmlCellsDocument doc = SingleXmlCellsDocument.Factory.newInstance();
|
||||
doc.setSingleXmlCells(singleXMLCells);
|
||||
doc.save(out, DEFAULT_XML_OPTIONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void commit() throws IOException {
|
||||
PackagePart part = getPackagePart();
|
||||
OutputStream out = part.getOutputStream();
|
||||
writeTo(out);
|
||||
out.close();
|
||||
}
|
||||
|
||||
public CTSingleXmlCells getCTSingleXMLCells(){
|
||||
return singleXMLCells;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return all the SimpleXmlCell contained in this SingleXmlCells element
|
||||
*/
|
||||
public List<XSSFSingleXmlCell> getAllSimpleXmlCell(){
|
||||
List<XSSFSingleXmlCell> list = new Vector<XSSFSingleXmlCell>();
|
||||
CTSingleXmlCell[] singleXMLCellArray = singleXMLCells.getSingleXmlCellArray();
|
||||
|
||||
for(CTSingleXmlCell singleXmlCell: singleXMLCellArray){
|
||||
list.add(new XSSFSingleXmlCell(singleXmlCell,this));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
248
src/ooxml/java/org/apache/poi/xssf/model/Table.java
Executable file
248
src/ooxml/java/org/apache/poi/xssf/model/Table.java
Executable file
@ -0,0 +1,248 @@
|
||||
/* ====================================================================
|
||||
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.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTable;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.TableDocument;
|
||||
|
||||
/**
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*
|
||||
* @author Roberto Manicardi
|
||||
*/
|
||||
public class Table extends POIXMLDocumentPart {
|
||||
|
||||
private CTTable ctTable;
|
||||
private List<XSSFXmlColumnPr> xmlColumnPr;
|
||||
private CellReference startCellReference;
|
||||
private CellReference endCellReference;
|
||||
private String commonXPath;
|
||||
|
||||
|
||||
public Table() {
|
||||
super();
|
||||
ctTable = CTTable.Factory.newInstance();
|
||||
|
||||
}
|
||||
|
||||
public Table(PackagePart part, PackageRelationship rel)
|
||||
throws IOException {
|
||||
super(part, rel);
|
||||
readFrom(part.getInputStream());
|
||||
}
|
||||
|
||||
public void readFrom(InputStream is) throws IOException {
|
||||
try {
|
||||
TableDocument doc = TableDocument.Factory.parse(is);
|
||||
ctTable = doc.getTable();
|
||||
} catch (XmlException e) {
|
||||
throw new IOException(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public XSSFSheet getXSSFSheet(){
|
||||
return (XSSFSheet) getParent();
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
TableDocument doc = TableDocument.Factory.newInstance();
|
||||
doc.setTable(ctTable);
|
||||
doc.save(out, DEFAULT_XML_OPTIONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void commit() throws IOException {
|
||||
PackagePart part = getPackagePart();
|
||||
OutputStream out = part.getOutputStream();
|
||||
writeTo(out);
|
||||
out.close();
|
||||
}
|
||||
|
||||
public CTTable getCTTable(){
|
||||
return ctTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this Table element contains even a single mapping to the map identified by id
|
||||
* @param id the XSSFMap ID
|
||||
* @return true if the Table element contain mappings
|
||||
*/
|
||||
public boolean mapsTo(long id){
|
||||
boolean maps =false;
|
||||
|
||||
List<XSSFXmlColumnPr> pointers = getXmlColumnPrs();
|
||||
|
||||
for(XSSFXmlColumnPr pointer: pointers){
|
||||
if(pointer.getMapId()==id){
|
||||
maps=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return maps;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Calculates the xpath of the root element for the table. This will be the common part
|
||||
* of all the mapping's xpaths
|
||||
*
|
||||
* @return the xpath of the table's root element
|
||||
*/
|
||||
public String getCommonXpath() {
|
||||
|
||||
if(commonXPath == null){
|
||||
|
||||
String[] commonTokens ={};
|
||||
|
||||
for(CTTableColumn column :ctTable.getTableColumns().getTableColumnArray()){
|
||||
if(column.getXmlColumnPr()!=null){
|
||||
String xpath = column.getXmlColumnPr().getXpath();
|
||||
String[] tokens = xpath.split("/");
|
||||
if(commonTokens.length==0){
|
||||
commonTokens = tokens;
|
||||
|
||||
}else{
|
||||
int maxLenght = commonTokens.length>tokens.length? tokens.length:commonTokens.length;
|
||||
for(int i =0; i<maxLenght;i++){
|
||||
if(!commonTokens[i].equals(tokens[i])){
|
||||
List<String> subCommonTokens = Arrays.asList(commonTokens).subList(0, i);
|
||||
|
||||
String[] container = {};
|
||||
|
||||
commonTokens = subCommonTokens.toArray(container);
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
commonXPath ="";
|
||||
|
||||
for(int i = 1 ; i< commonTokens.length;i++){
|
||||
commonXPath +="/"+commonTokens[i];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return commonXPath;
|
||||
}
|
||||
|
||||
|
||||
public List<XSSFXmlColumnPr> getXmlColumnPrs() {
|
||||
|
||||
if(xmlColumnPr==null){
|
||||
xmlColumnPr = new Vector<XSSFXmlColumnPr>();
|
||||
for(CTTableColumn column:ctTable.getTableColumns().getTableColumnArray()){
|
||||
if(column.getXmlColumnPr()!=null){
|
||||
XSSFXmlColumnPr columnPr = new XSSFXmlColumnPr(this,column,column.getXmlColumnPr());
|
||||
xmlColumnPr.add(columnPr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return xmlColumnPr;
|
||||
}
|
||||
|
||||
/**
|
||||
* the number of mapped table columns (see Open Office XML Part 4: chapter 3.5.1.4)
|
||||
* @return
|
||||
*/
|
||||
public long getNumerOfMappedColumns(){
|
||||
return ctTable.getTableColumns().getCount();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* @return
|
||||
*/
|
||||
public CellReference getStartCellReference() {
|
||||
|
||||
if(startCellReference==null){
|
||||
String ref = ctTable.getRef();
|
||||
String[] boundaries = ref.split(":");
|
||||
String from = boundaries[0];
|
||||
startCellReference = new CellReference(from);
|
||||
}
|
||||
return startCellReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* The reference for the cell in the bottom-right part of the table
|
||||
* (see Open Office XML Part 4: chapter 3.5.1.2, attribute ref)
|
||||
* @return
|
||||
*/
|
||||
public CellReference getEndCellReference() {
|
||||
|
||||
if(endCellReference==null){
|
||||
|
||||
String ref = ctTable.getRef();
|
||||
String[] boundaries = ref.split(":");
|
||||
String from = boundaries[1];
|
||||
endCellReference = new CellReference(from);
|
||||
}
|
||||
return endCellReference;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the total number of rows in the selection. (Note: in this version autofiltering is ignored)
|
||||
* @return
|
||||
*/
|
||||
public int getRowCount(){
|
||||
|
||||
|
||||
CellReference from = getStartCellReference();
|
||||
CellReference to = getEndCellReference();
|
||||
|
||||
int rowCount = -1;
|
||||
if (from!=null && to!=null){
|
||||
rowCount = to.getRow()-from.getRow();
|
||||
}
|
||||
return rowCount;
|
||||
}
|
||||
}
|
120
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFMap.java
Executable file
120
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFMap.java
Executable file
@ -0,0 +1,120 @@
|
||||
/* ====================================================================
|
||||
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 java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.poi.xssf.model.MapInfo;
|
||||
import org.apache.poi.xssf.model.SingleXmlCells;
|
||||
import org.apache.poi.xssf.model.Table;
|
||||
import org.apache.poi.xssf.usermodel.helpers.XSSFSingleXmlCell;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMap;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSchema;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* This class implements the Map element (Open Office XML Part 4:
|
||||
* chapter 3.16.2)
|
||||
* <p/>
|
||||
* This element contains all of the properties related to the XML map,
|
||||
* and the behaviors expected during data refresh operations.
|
||||
*
|
||||
* @author Roberto Manicardi
|
||||
*/
|
||||
|
||||
|
||||
public class XSSFMap {
|
||||
|
||||
private CTMap ctMap;
|
||||
|
||||
private MapInfo mapInfo;
|
||||
|
||||
|
||||
public XSSFMap(CTMap ctMap, MapInfo mapInfo) {
|
||||
this.ctMap = ctMap;
|
||||
this.mapInfo = mapInfo;
|
||||
}
|
||||
|
||||
|
||||
public CTMap getCtMap() {
|
||||
return ctMap;
|
||||
}
|
||||
|
||||
|
||||
public CTSchema getCTSchema() {
|
||||
String schemaId = ctMap.getSchemaID();
|
||||
return mapInfo.getCTSchemaById(schemaId);
|
||||
}
|
||||
|
||||
public Node getSchema() {
|
||||
Node xmlSchema = null;
|
||||
|
||||
CTSchema schema = getCTSchema();
|
||||
xmlSchema = schema.getDomNode().getFirstChild();
|
||||
|
||||
return xmlSchema;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of Single Xml Cells that provide a map rule to this mapping.
|
||||
*/
|
||||
public List<XSSFSingleXmlCell> getRelatedSingleXMLCell() {
|
||||
List<XSSFSingleXmlCell> relatedSimpleXmlCells = new Vector<XSSFSingleXmlCell>();
|
||||
|
||||
int sheetNumber = mapInfo.getWorkbook().getNumberOfSheets();
|
||||
for (int i = 0; i < sheetNumber; i++) {
|
||||
XSSFSheet sheet = mapInfo.getWorkbook().getSheetAt(i);
|
||||
for (POIXMLDocumentPart p : sheet.getRelations()) {
|
||||
if (p instanceof SingleXmlCells) {
|
||||
SingleXmlCells singleXMLCells = (SingleXmlCells) p;
|
||||
for (XSSFSingleXmlCell cell : singleXMLCells.getAllSimpleXmlCell()) {
|
||||
if (cell.getMapId() == ctMap.getID()) {
|
||||
relatedSimpleXmlCells.add(cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return relatedSimpleXmlCells;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of all Tables that provide a map rule to this mapping
|
||||
*/
|
||||
public List<Table> getRelatedTables() {
|
||||
|
||||
List<Table> tables = new Vector<Table>();
|
||||
int sheetNumber = mapInfo.getWorkbook().getNumberOfSheets();
|
||||
|
||||
for (int i = 0; i < sheetNumber; i++) {
|
||||
XSSFSheet sheet = mapInfo.getWorkbook().getSheetAt(i);
|
||||
for (POIXMLDocumentPart p : sheet.getRelations()) {
|
||||
if (p.getPackageRelationship().getRelationshipType().equals(XSSFRelation.TABLE.getRelation())) {
|
||||
Table table = (Table) p;
|
||||
if (table.mapsTo(ctMap.getID())) {
|
||||
tables.add(table);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
}
|
@ -25,10 +25,13 @@ import java.util.HashMap;
|
||||
import org.apache.poi.POIXMLDocument;
|
||||
import org.apache.poi.POIXMLRelation;
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.poi.xssf.model.MapInfo;
|
||||
import org.apache.poi.xssf.model.SingleXmlCells;
|
||||
import org.apache.poi.xssf.model.StylesTable;
|
||||
import org.apache.poi.xssf.model.SharedStringsTable;
|
||||
import org.apache.poi.xssf.model.CommentsTable;
|
||||
import org.apache.poi.xssf.model.CalculationChain;
|
||||
import org.apache.poi.xssf.model.Table;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
@ -93,6 +96,28 @@ public final class XSSFRelation extends POIXMLRelation {
|
||||
"/xl/drawings/vmlDrawing#.vml",
|
||||
null
|
||||
);
|
||||
|
||||
public static final XSSFRelation CUSTOM_XML_MAPPINGS = new XSSFRelation(
|
||||
"application/xml",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/xmlMaps",
|
||||
"/xl/xmlMaps.xml",
|
||||
MapInfo.class
|
||||
);
|
||||
|
||||
public static final XSSFRelation SINGLE_XML_CELLS = new XSSFRelation(
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableSingleCells",
|
||||
"/tables/tableSingleCells#.xml",
|
||||
SingleXmlCells.class
|
||||
);
|
||||
|
||||
public static final XSSFRelation TABLE = new XSSFRelation(
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/table",
|
||||
"/tables/table#.xml",
|
||||
Table.class
|
||||
);
|
||||
|
||||
public static final XSSFRelation IMAGES = new XSSFRelation(
|
||||
null,
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
||||
|
@ -22,12 +22,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
@ -56,6 +51,8 @@ import org.apache.poi.util.PackageHelper;
|
||||
import org.apache.poi.xssf.model.CalculationChain;
|
||||
import org.apache.poi.xssf.model.SharedStringsTable;
|
||||
import org.apache.poi.xssf.model.StylesTable;
|
||||
import org.apache.poi.xssf.model.MapInfo;
|
||||
import org.apache.poi.xssf.extractor.XSSFExportToXml;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.apache.xmlbeans.XmlObject;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
@ -106,6 +103,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
||||
*/
|
||||
private CalculationChain calcChain;
|
||||
|
||||
/**
|
||||
* A collection of custom XML mappings
|
||||
*/
|
||||
private MapInfo mapInfo;
|
||||
|
||||
/**
|
||||
* Used to keep track of the data formatter so that all
|
||||
* createDataFormatter calls return the same one for a given
|
||||
@ -174,6 +176,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
||||
if(p instanceof SharedStringsTable) sharedStringSource = (SharedStringsTable)p;
|
||||
else if(p instanceof StylesTable) stylesSource = (StylesTable)p;
|
||||
else if(p instanceof CalculationChain) calcChain = (CalculationChain)p;
|
||||
else if(p instanceof MapInfo) mapInfo = (MapInfo)p;
|
||||
else if (p instanceof XSSFSheet) {
|
||||
shIdMap.put(p.getPackageRelationship().getId(), (XSSFSheet)p);
|
||||
}
|
||||
@ -1282,4 +1285,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
||||
return calcChain;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return a collection of custom XML mappings defined in this workbook
|
||||
*/
|
||||
public Collection<XSSFMap> getCustomXMLMappings(){
|
||||
return mapInfo == null ? new ArrayList<XSSFMap>() : mapInfo.getAllXSSFMaps();
|
||||
}
|
||||
}
|
||||
|
84
src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFSingleXmlCell.java
Executable file
84
src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFSingleXmlCell.java
Executable file
@ -0,0 +1,84 @@
|
||||
/* ====================================================================
|
||||
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.helpers;
|
||||
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.xssf.model.SingleXmlCells;
|
||||
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSingleXmlCell;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXmlCellPr;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXmlPr;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXmlDataType.Enum;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class is a wrapper around the CTSingleXmlCell (Open Office XML Part 4:
|
||||
* chapter 3.5.2.1)
|
||||
*
|
||||
|
||||
*
|
||||
* @author Roberto Manicardi
|
||||
*
|
||||
*/
|
||||
public class XSSFSingleXmlCell {
|
||||
|
||||
private CTSingleXmlCell singleXmlCell;
|
||||
private SingleXmlCells parent;
|
||||
|
||||
|
||||
public XSSFSingleXmlCell(CTSingleXmlCell singleXmlCell, SingleXmlCells parent){
|
||||
this.singleXmlCell = singleXmlCell;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the XSSFCell referenced by the R attribute
|
||||
* @return the referenced XSSFCell, null if the cell reference is invalid
|
||||
*/
|
||||
public XSSFCell getReferencedCell(){
|
||||
XSSFCell cell = null;
|
||||
|
||||
|
||||
CellReference cellReference = new CellReference(singleXmlCell.getR());
|
||||
|
||||
XSSFRow row = parent.getXSSFSheet().getRow(cellReference.getRow());
|
||||
cell = row.getCell(cellReference.getCol());
|
||||
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
public String getXpath(){
|
||||
CTXmlCellPr xmlCellPr = singleXmlCell.getXmlCellPr();
|
||||
CTXmlPr xmlPr = xmlCellPr.getXmlPr();
|
||||
String xpath = xmlPr.getXpath();
|
||||
return xpath;
|
||||
}
|
||||
|
||||
public long getMapId(){
|
||||
return singleXmlCell.getXmlCellPr().getXmlPr().getMapId();
|
||||
}
|
||||
|
||||
public Enum getXmlDataType() {
|
||||
CTXmlCellPr xmlCellPr = singleXmlCell.getXmlCellPr();
|
||||
CTXmlPr xmlPr = xmlCellPr.getXmlPr();
|
||||
return xmlPr.getXmlDataType();
|
||||
}
|
||||
|
||||
}
|
65
src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFXmlColumnPr.java
Executable file
65
src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFXmlColumnPr.java
Executable file
@ -0,0 +1,65 @@
|
||||
/* ====================================================================
|
||||
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.helpers;
|
||||
|
||||
import org.apache.poi.xssf.model.Table;
|
||||
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:
|
||||
* chapter 3.5.1.7)
|
||||
*
|
||||
*
|
||||
* @author Roberto Manicardi
|
||||
*/
|
||||
public class XSSFXmlColumnPr {
|
||||
|
||||
private Table table;
|
||||
private CTTableColumn ctTableColumn;
|
||||
private CTXmlColumnPr ctXmlColumnPr;
|
||||
|
||||
public XSSFXmlColumnPr(Table table ,CTTableColumn ctTableColum,CTXmlColumnPr ctXmlColumnPr){
|
||||
this.table = table;
|
||||
this.ctTableColumn = ctTableColum;
|
||||
this.ctXmlColumnPr = ctXmlColumnPr;
|
||||
}
|
||||
|
||||
public long getMapId(){
|
||||
return ctXmlColumnPr.getMapId();
|
||||
}
|
||||
|
||||
public String getLocalXPath(){
|
||||
String localXPath = "";
|
||||
int numberOfCommonXPathAxis = table.getCommonXpath().split("/").length-1;
|
||||
|
||||
String[] xPathTokens = ctXmlColumnPr.getXpath().split("/");
|
||||
for(int i=numberOfCommonXPathAxis; i<xPathTokens.length;i++){
|
||||
localXPath += "/" +xPathTokens[i];
|
||||
}
|
||||
return localXPath;
|
||||
}
|
||||
|
||||
public Enum getXmlDataType() {
|
||||
return ctXmlColumnPr.getXmlDataType();
|
||||
}
|
||||
|
||||
}
|
220
src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFExportToXML.java
Executable file
220
src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFExportToXML.java
Executable file
@ -0,0 +1,220 @@
|
||||
/* ====================================================================
|
||||
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.extractor;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||
import org.apache.poi.xssf.model.MapInfo;
|
||||
import org.apache.poi.xssf.usermodel.XSSFMap;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Roberto Manicardi
|
||||
*
|
||||
*/
|
||||
public class TestXSSFExportToXML extends TestCase{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void testExportToXML() throws Exception{
|
||||
|
||||
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXmlMappings.xlsx");
|
||||
|
||||
|
||||
|
||||
MapInfo mapInfo = null;
|
||||
|
||||
for(POIXMLDocumentPart p : wb.getRelations()){
|
||||
|
||||
|
||||
if(p instanceof MapInfo){
|
||||
mapInfo = (MapInfo) p;
|
||||
|
||||
|
||||
XSSFMap map = mapInfo.getXSSFMapById(1);
|
||||
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
exporter.exportToXML(os,true);
|
||||
String xml = os.toString("UTF-8");
|
||||
|
||||
assertNotNull(xml);
|
||||
assertTrue(!xml.equals(""));
|
||||
|
||||
|
||||
String docente = xml.split("<DOCENTE>")[1].split("</DOCENTE>")[0].trim();
|
||||
String nome = xml.split("<NOME>")[1].split("</NOME>")[0].trim();
|
||||
String tutor = xml.split("<TUTOR>")[1].split("</TUTOR>")[0].trim();
|
||||
String cdl = xml.split("<CDL>")[1].split("</CDL>")[0].trim();
|
||||
String durata = xml.split("<DURATA>")[1].split("</DURATA>")[0].trim();
|
||||
String argomento = xml.split("<ARGOMENTO>")[1].split("</ARGOMENTO>")[0].trim();
|
||||
String progetto = xml.split("<PROGETTO>")[1].split("</PROGETTO>")[0].trim();
|
||||
String crediti = xml.split("<CREDITI>")[1].split("</CREDITI>")[0].trim();
|
||||
|
||||
assertEquals("ro",docente);
|
||||
assertEquals("ro",nome);
|
||||
assertEquals("ds",tutor);
|
||||
assertEquals("gs",cdl);
|
||||
assertEquals("g",durata);
|
||||
assertEquals("gvvv",argomento);
|
||||
assertEquals("aaaa",progetto);
|
||||
assertEquals("aa",crediti);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testExportToXMLInverseOrder() throws Exception{
|
||||
|
||||
|
||||
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXmlMappings-inverse-order.xlsx");
|
||||
|
||||
MapInfo mapInfo = null;
|
||||
|
||||
for(POIXMLDocumentPart p : wb.getRelations()){
|
||||
|
||||
|
||||
if(p instanceof MapInfo){
|
||||
mapInfo = (MapInfo) p;
|
||||
|
||||
|
||||
XSSFMap map = mapInfo.getXSSFMapById(1);
|
||||
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
exporter.exportToXML(os,true);
|
||||
String xml = os.toString("UTF-8");
|
||||
|
||||
assertNotNull(xml);
|
||||
assertTrue(!xml.equals(""));
|
||||
|
||||
String docente = xml.split("<DOCENTE>")[1].split("</DOCENTE>")[0].trim();
|
||||
String nome = xml.split("<NOME>")[1].split("</NOME>")[0].trim();
|
||||
String tutor = xml.split("<TUTOR>")[1].split("</TUTOR>")[0].trim();
|
||||
String cdl = xml.split("<CDL>")[1].split("</CDL>")[0].trim();
|
||||
String durata = xml.split("<DURATA>")[1].split("</DURATA>")[0].trim();
|
||||
String argomento = xml.split("<ARGOMENTO>")[1].split("</ARGOMENTO>")[0].trim();
|
||||
String progetto = xml.split("<PROGETTO>")[1].split("</PROGETTO>")[0].trim();
|
||||
String crediti = xml.split("<CREDITI>")[1].split("</CREDITI>")[0].trim();
|
||||
|
||||
assertEquals("aa",nome);
|
||||
assertEquals("aaaa",docente);
|
||||
assertEquals("gvvv",tutor);
|
||||
assertEquals("g",cdl);
|
||||
assertEquals("gs",durata);
|
||||
assertEquals("ds",argomento);
|
||||
assertEquals("ro",progetto);
|
||||
assertEquals("ro",crediti);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void testXPathOrdering() throws Exception{
|
||||
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXmlMappings-inverse-order.xlsx");
|
||||
|
||||
MapInfo mapInfo = null;
|
||||
|
||||
for(POIXMLDocumentPart p : wb.getRelations()){
|
||||
|
||||
|
||||
if(p instanceof MapInfo){
|
||||
mapInfo = (MapInfo) p;
|
||||
|
||||
XSSFMap map = mapInfo.getXSSFMapById(1);
|
||||
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||
|
||||
assertEquals(1,exporter.compare("/CORSO/DOCENTE", "/CORSO/NOME"));
|
||||
|
||||
assertEquals(-1,exporter.compare("/CORSO/NOME", "/CORSO/DOCENTE"));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void testMultiTable() throws Exception{
|
||||
|
||||
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMappings-complex-type.xlsx");
|
||||
|
||||
for(POIXMLDocumentPart p : wb.getRelations()){
|
||||
|
||||
|
||||
if(p instanceof MapInfo){
|
||||
MapInfo mapInfo = (MapInfo) p;
|
||||
|
||||
XSSFMap map = mapInfo.getXSSFMapById(2);
|
||||
|
||||
assertNotNull(map);
|
||||
|
||||
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
exporter.exportToXML(os,true);
|
||||
String xml = os.toString("UTF-8");
|
||||
|
||||
assertNotNull(xml);
|
||||
|
||||
String[] regexConditions = { "<MapInfo",
|
||||
"</MapInfo>",
|
||||
"<Schema ID=\"1\" Namespace=\"\" SchemaRef=\"\"/>",
|
||||
"<Schema ID=\"4\" Namespace=\"\" SchemaRef=\"\"/>",
|
||||
"DataBinding",
|
||||
"Map Append=\"false\" AutoFit=\"false\" ID=\"1\"",
|
||||
"Map Append=\"false\" AutoFit=\"false\" ID=\"5\""
|
||||
|
||||
};
|
||||
|
||||
for(String condition : regexConditions){
|
||||
Pattern pattern = Pattern.compile(condition);
|
||||
Matcher matcher = pattern.matcher(xml);
|
||||
assertTrue(matcher.find());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
84
src/ooxml/testcases/org/apache/poi/xssf/model/TestMapInfo.java
Executable file
84
src/ooxml/testcases/org/apache/poi/xssf/model/TestMapInfo.java
Executable file
@ -0,0 +1,84 @@
|
||||
/* ====================================================================
|
||||
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.model;
|
||||
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||
import org.apache.poi.xssf.usermodel.XSSFMap;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSchema;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMapInfo;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Roberto Manicardi
|
||||
*/
|
||||
public class TestMapInfo extends TestCase {
|
||||
|
||||
|
||||
public void testMapInfoExists() throws Exception {
|
||||
|
||||
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXmlMappings.xlsx");
|
||||
|
||||
MapInfo mapInfo = null;
|
||||
SingleXmlCells singleXMLCells = null;
|
||||
|
||||
for (POIXMLDocumentPart p : wb.getRelations()) {
|
||||
|
||||
|
||||
if (p instanceof MapInfo) {
|
||||
mapInfo = (MapInfo) p;
|
||||
|
||||
|
||||
CTMapInfo ctMapInfo = mapInfo.getCTMapInfo();
|
||||
|
||||
assertNotNull(ctMapInfo);
|
||||
|
||||
CTSchema[] schemas = ctMapInfo.getSchemaArray();
|
||||
assertEquals(1, schemas.length);
|
||||
|
||||
|
||||
for (XSSFMap map : mapInfo) {
|
||||
Node xmlSchema = map.getSchema();
|
||||
assertNotNull(xmlSchema);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XSSFSheet sheet1 = wb.getSheetAt(0);
|
||||
|
||||
for (POIXMLDocumentPart p : sheet1.getRelations()) {
|
||||
|
||||
if (p instanceof SingleXmlCells) {
|
||||
singleXMLCells = (SingleXmlCells) p;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
assertNotNull(mapInfo);
|
||||
assertNotNull(singleXMLCells);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
BIN
src/testcases/org/apache/poi/hssf/data/CustomXMLMappings-complex-type.xlsx
Executable file
BIN
src/testcases/org/apache/poi/hssf/data/CustomXMLMappings-complex-type.xlsx
Executable file
Binary file not shown.
BIN
src/testcases/org/apache/poi/hssf/data/CustomXMLMappings.xlsx
Executable file
BIN
src/testcases/org/apache/poi/hssf/data/CustomXMLMappings.xlsx
Executable file
Binary file not shown.
BIN
src/testcases/org/apache/poi/hssf/data/CustomXmlMappings-inverse-order.xlsx
Executable file
BIN
src/testcases/org/apache/poi/hssf/data/CustomXmlMappings-inverse-order.xlsx
Executable file
Binary file not shown.
Loading…
Reference in New Issue
Block a user