I have part of code that generates Excel document using OpenXML.
The problem is to set custom column width. This question is frequently
discussed herew on SO, but unfortunately nothing helped to me.
So here the code of creating file:
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(stream
, SpreadsheetDocumentType.Workbook);
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.
AppendChild<Sheets>(new Sheets());
Sheet sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.
GetIdOfPart(worksheetPart),
SheetId = 1,
Name = _sheetName
};
sheets.Append(sheet);
document = spreadsheetDocument;
wbPart = workbookpart
After creating I am trying to set custom column width to the first column
Worksheet ws = ((WorksheetPart)(wbPart.GetPartById(sheet.Id))).Worksheet;
Columns columns = new Columns();
Column column = new Column() { Min = (UInt32Value)5U, Max = (UInt32Value)5U,
Width = 16D, CustomWidth = true };
columns.Append(column);
ws.Append(columns);
ws.Save();
Code runs without any exceptions, but result file is broken
Here is the structure opf result sheet xml
<?xml version="1.0" encoding="UTF-8"?>
-<x:worksheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
-<x:sheetData>
-<x:row r="7">
-<x:c r="A7" t="s" s="6">
<x:v>11</x:v>
</x:c>
-<x:c r="B7" t="s" s="6">
<x:v>12</x:v>
</x:c>
-<x:c r="C7" t="s" s="6">
<x:v>13</x:v>
</x:c>
</x:row>
</x:sheetData>
-<x:cols>
<x:col customWidth="1" width="16" max="5" min="5"/>
</x:cols>
</x:worksheet>
So the question is, what am I doing wrong ?
UPD. Problem solved, thanks to petelids.
I just added :
SheetData sheetData = ws.GetFirstChild<SheetData>();
ws.InsertBefore(columns,sheetData);
And then, only specify the range here Min = (UInt32Value)5U, Max = (UInt32Value)5U
You have the order of your elements incorrect which leads to a corrupted file message. The ECMA-376 standard defines the XML for a Worksheet as
<xsd:complexType name="CT_Worksheet">
<xsd:sequence>
<xsd:element name="sheetPr" type="CT_SheetPr" minOccurs="0" maxOccurs="1"/>
<xsd:element name="dimension" type="CT_SheetDimension" minOccurs="0" maxOccurs="1"/>
<xsd:element name="sheetViews" type="CT_SheetViews" minOccurs="0" maxOccurs="1"/>
<xsd:element name="sheetFormatPr" type="CT_SheetFormatPr" minOccurs="0" maxOccurs="1"/>
<xsd:element name="cols" type="CT_Cols" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="sheetData" type="CT_SheetData" minOccurs="1" maxOccurs="1"/>
<xsd:element name="sheetCalcPr" type="CT_SheetCalcPr" minOccurs="0" maxOccurs="1"/>
<xsd:element name="sheetProtection" type="CT_SheetProtection" minOccurs="0" maxOccurs="1"/>
<xsd:element name="protectedRanges" type="CT_ProtectedRanges" minOccurs="0" maxOccurs="1"/>
<xsd:element name="scenarios" type="CT_Scenarios" minOccurs="0" maxOccurs="1"/>
<xsd:element name="autoFilter" type="CT_AutoFilter" minOccurs="0" maxOccurs="1"/>
<xsd:element name="sortState" type="CT_SortState" minOccurs="0" maxOccurs="1"/>
<xsd:element name="dataConsolidate" type="CT_DataConsolidate" minOccurs="0" maxOccurs="1"/>
<xsd:element name="customSheetViews" type="CT_CustomSheetViews" minOccurs="0" maxOccurs="1"/>
<xsd:element name="mergeCells" type="CT_MergeCells" minOccurs="0" maxOccurs="1"/>
<xsd:element name="phoneticPr" type="CT_PhoneticPr" minOccurs="0" maxOccurs="1"/>
<xsd:element name="conditionalFormatting" type="CT_ConditionalFormatting" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="dataValidations" type="CT_DataValidations" minOccurs="0" maxOccurs="1"/>
<xsd:element name="hyperlinks" type="CT_Hyperlinks" minOccurs="0" maxOccurs="1"/>
<xsd:element name="printOptions" type="CT_PrintOptions" minOccurs="0" maxOccurs="1"/>
<xsd:element name="pageMargins" type="CT_PageMargins" minOccurs="0" maxOccurs="1"/>
<xsd:element name="pageSetup" type="CT_PageSetup" minOccurs="0" maxOccurs="1"/>
<xsd:element name="headerFooter" type="CT_HeaderFooter" minOccurs="0" maxOccurs="1"/>
<xsd:element name="rowBreaks" type="CT_PageBreak" minOccurs="0" maxOccurs="1"/>
<xsd:element name="colBreaks" type="CT_PageBreak" minOccurs="0" maxOccurs="1"/>
<xsd:element name="customProperties" type="CT_CustomProperties" minOccurs="0" maxOccurs="1"/>
<xsd:element name="cellWatches" type="CT_CellWatches" minOccurs="0" maxOccurs="1"/>
<xsd:element name="ignoredErrors" type="CT_IgnoredErrors" minOccurs="0" maxOccurs="1"/>
<xsd:element name="smartTags" type="CT_SmartTags" minOccurs="0" maxOccurs="1"/>
<xsd:element name="drawing" type="CT_Drawing" minOccurs="0" maxOccurs="1"/>
<xsd:element name="drawingHF" type="CT_DrawingHF" minOccurs="0" maxOccurs="1"/>
<xsd:element name="picture" type="CT_SheetBackgroundPicture" minOccurs="0" maxOccurs="1"/>
<xsd:element name="oleObjects" type="CT_OleObjects" minOccurs="0" maxOccurs="1"/>
<xsd:element name="controls" type="CT_Controls" minOccurs="0" maxOccurs="1"/>
<xsd:element name="webPublishItems" type="CT_WebPublishItems" minOccurs="0" maxOccurs="1"/>
<xsd:element name="tableParts" type="CT_TableParts" minOccurs="0" maxOccurs="1"/>
<xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
Notice that it's a sequence so the order of the items matters and cols comes before sheetData (lines 5 and 6).
In your case you need to add the Columns directly before SheetData. There's an InsertBefore method on the Worksheet which can be used in place of your call to Append.
Related
I've found similar questions but some of the conditions don't apply to my case or the answers do not work.
I created a CXF (3.2.1) SOAP client to consume an external web service so I don't have control over the WSDL and schemas.
The relevant part (not the entire schema) of the service schema is:
<xsd:complexType name="LegalEntityService1">
<xsd:annotation>
<xsd:appinfo source="http://xmlns.oracle.com/adf/svc/metadata/">
<key xmlns="http://xmlns.oracle.com/adf/svc/metadata/">
<attribute>LegalEntityId</attribute>
</key>
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element minOccurs="0" name="LegalEntityId" type="xsd:long" sdoXML:dataType="sdoJava:LongObject"/>
<xsd:element minOccurs="0" name="PartyId" type="xsd:long" sdoXML:dataType="sdoJava:LongObject"/>
<xsd:element minOccurs="0" name="LegalEntityIdentifier" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="Name" type="xsd:string"/>
<xsd:element default="1" minOccurs="0" name="GeographyId" type="xsd:long" sdoXML:dataType="sdoJava:LongObject"/>
<xsd:element minOccurs="0" name="TransactingEntityFlag" nillable="true" type="xsd:boolean"/>
<xsd:element minOccurs="0" name="EffectiveFrom" nillable="true" type="ns0:date-Date"/>
<xsd:element minOccurs="0" name="EffectiveTo" nillable="true" type="ns0:date-Date"/>
<xsd:element minOccurs="0" name="ObjectVersionNumber" type="xsd:int" sdoXML:dataType="sdoJava:IntObject"/>
<xsd:element minOccurs="0" name="ActivityCode" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="SubActivityCode" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="TypeOfCompany" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="RegistrationCodeLe" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="RegistrationCodeEtb" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="RegistrationCodeLeValue" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="RegistrationCodeEtbValue" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="JurisdictionName" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="PlaceOfRegistration" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="LegalEmployerFlag" nillable="true" type="xsd:boolean"/>
<xsd:element minOccurs="0" name="ParentPsuId" nillable="true" type="xsd:long"/>
<xsd:element minOccurs="0" name="PsuFlag" nillable="true" type="xsd:boolean"/>
<xsd:element minOccurs="0" name="JurisdictionId" nillable="true" type="xsd:long"/>
<xsd:element minOccurs="0" name="GeographyId1" type="xsd:long" sdoXML:dataType="sdoJava:LongObject"/>
<xsd:element minOccurs="0" name="TerritoryShortName" type="xsd:string"/>
<xsd:element minOccurs="0" name="TerritoryCode" type="xsd:string"/>
<xsd:element minOccurs="0" name="Country" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="LegalAddress" type="xsd:string"/>
<xsd:element minOccurs="0" name="Name1" type="xsd:string"/>
<xsd:element minOccurs="0" name="LegalEntityId1" type="xsd:long" sdoXML:dataType="sdoJava:LongObject"/>
I'm specifically having problems with:
<xsd:element minOccurs="0" name="LegalEntityId1" type="xsd:long" sdoXML:dataType="sdoJava:LongObject"/>
It is minOccurs=0 so it should allow an empty tag but when it unmarshalles the following response it fails with javax.xml.ws.soap.SOAPFaultException: Unmarshalling Error: For input string: "".
The annotation seems correct as it is required=false.
#XmlElementRef(name = "LegalEntityId1", namespace = "http://xmlns.oracle.com/apps/financials/legalEntity/legalEntities/legalEntityService/", type = JAXBElement.class, required = false)
protected JAXBElement<Long> legalEntityId1;
I don't understand why it is failing. I know the problem is LegalEntityId1 because I checked it with the debugger.
EDIT #1
Here is the entire stacktrace https://pastebin.com/jS9Pu4rB.
This issue was due to the type of the element.
<LegalEntityId1></LegalEntityId1> this is not a Long format because it is parsed as "" empty string.
if you need instead a "null" meaning, that in xml is "nil" you should change your xsd in <xsd:element minOccurs="0" name="LegalEntityId1" type="xsd:long" nillable="true" /> that in xml will be <LegalEntityId1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/> .
Can you have an allready restricted type and then derive from this type by extension and add elements that do not fit to a base type?
<xsd:complexType name="absHcontainerType">
<xsd:complexContent>
<xsd:restriction base="e:urContentType">
<xsd:sequence>
<xsd:element ref="e:absMcontainer" minOccurs="0"
maxOccurs="1" />
<xsd:element ref="e:absHtitle" minOccurs="1" maxOccurs="unbounded" />
<xsd:choice minOccurs="1" maxOccurs="unbounded">
<xsd:element ref="e:absMcontainer" />
<xsd:element ref="e:absHcontainer" />
<xsd:element ref="e:absContainer" />
</xsd:choice>
</xsd:sequence>
<xsd:attributeGroup ref="e:typehcontainer" />
<xsd:attributeGroup ref="e:anyattr" />
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
And then derive this like this:
<xsd:complexType name="absHcontainerType2">
<xsd:complexContent>
<xsd:extension base="absHcontainerType">
<xs:sequence>
<xs:element name="xy" type="xs:string"/>
<xs:element name="xyz" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xsd:complexContent>
</xsd:complexType>
As long as you don't put back things that got restricted away, I wouldn't expect a problem. Are you in fact getting an error when you try it?
I have a form that I am defining in my Xquery request. This form is built on an XSD schema.
My form:
<xsd:element name="AddInsuranceToOrderForm">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="OrderId" type="xsd:long" minOccurs="1" maxOccurs="1"/>
<xsd:element name="DistributionChannel" type="xsd:long" minOccurs="1" maxOccurs="1"/>
<xsd:element name="FloatNumber" type="xsd:long" minOccurs="1" maxOccurs="1"/>
<xsd:element name="UserId" type="xsd:long" minOccurs="1" maxOccurs="1"/>
<xsd:element name="SalesId" type="xsd:long" minOccurs="1" maxOccurs="1"/>
<xsd:element name="TotalDue" type="xsd:decimal" minOccurs="1" maxOccurs="1"/>
<xsd:element name="ChangeDue" type="xsd:decimal" minOccurs="1" maxOccurs="1"/>
**<xsd:element ref="tns:tenderItem" minOccurs="0" maxOccurs="unbounded"/>**
<xsd:element name="ProtectionPlans" type="tns:ProtectionPlanItemType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="InsurancePlans" type="tns:FeatureItemType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Notice tenderItems is a ref. It's source is here:
<xsd:element abstract="true" name="tenderItem" type="tns:TenderType"/>
<xsd:complexType name="TenderType">
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="0" name="date" type="xsd:dateTime"/>
<xsd:element maxOccurs="1" minOccurs="0" name="lineNumber" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="tenderId" type="xsd:long"/>
<xsd:element maxOccurs="1" minOccurs="0" name="returnTenderId" type="xsd:long"/>
<xsd:element maxOccurs="1" minOccurs="0" name="tenderType" type="tns:TenderTypeType"/>
<xsd:element maxOccurs="1" minOccurs="0" name="amount" type="xsd:decimal"/>
<xsd:element maxOccurs="1" minOccurs="0" name="signature" type="tns:SignatureType"/>
</xsd:sequence>
</xsd:complexType>
There are several specific tenders that extend tenderType that I want to add to my Xquery request. Here is an example:
<xsd:element name="billToAccount" substitutionGroup="tns:tenderItem" type="tns:BillToAccountType"/>
<xsd:complexType name="BillToAccountType">
<xsd:complexContent>
<xsd:extension base="tns:TenderType">
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="0" name="accountId" type="xsd:long"/>
<xsd:element maxOccurs="1" minOccurs="0" name="subscriptionId" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="chargeDescription" type="xsd:string"/>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="lineItems" type="tns:BillToAccountLineItemType"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
So how is this done in Xquery? I've tried the following:
{
for $BillToAccount in $addInsuranceToOrderABM1/ns3:MessagePayload/ns3:AddInsuranceToOrder/ns1:AddInsuranceToOrderDataArea/ns2:TenderItem
return
<ns2:billToAccount>
{
for $Date in $BillToAccount/ns0:Date
return
<ns2:date>{ data($Date) }</ns2:date>
}…
}
I did this for each tenderType, but the XML elements are not supported by the mapper.
You can use schema-element(ns3:tenderItem) to match any element in that substitution-group.
import schema default element namespace "http://www.example.com/xml-namespace/" at "schema.xsd";
declare variable $input as schema-element(AddInsuranceToOrderForm)
:= validate { doc('data.xml')/AddInsuranceToOrderForm };
for $item in $input/schema-element(tenderItem)
return $item
With schema.xsd as:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
xmlns:tns="http://www.example.com/xml-namespace/"
targetNamespace="http://www.example.com/xml-namespace/">
<xsd:element name="AddInsuranceToOrderForm">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="OrderId" type="xsd:long" minOccurs="1" maxOccurs="1"/>
<xsd:element name="DistributionChannel" type="xsd:long" minOccurs="1" maxOccurs="1"/>
<xsd:element name="FloatNumber" type="xsd:long" minOccurs="1" maxOccurs="1"/>
<xsd:element name="UserId" type="xsd:long" minOccurs="1" maxOccurs="1"/>
<xsd:element name="SalesId" type="xsd:long" minOccurs="1" maxOccurs="1"/>
<xsd:element name="TotalDue" type="xsd:decimal" minOccurs="1" maxOccurs="1"/>
<xsd:element name="ChangeDue" type="xsd:decimal" minOccurs="1" maxOccurs="1"/>
<xsd:element ref="tns:tenderItem" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element abstract="true" name="tenderItem" type="tns:TenderType"/>
<xsd:complexType name="TenderType">
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="0" name="date" type="xsd:dateTime"/>
<xsd:element maxOccurs="1" minOccurs="0" name="lineNumber" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="tenderId" type="xsd:long"/>
<xsd:element maxOccurs="1" minOccurs="0" name="returnTenderId" type="xsd:long"/>
<xsd:element maxOccurs="1" minOccurs="0" name="amount" type="xsd:decimal"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="BillToAccount" substitutionGroup="tns:tenderItem" type="tns:BillToAccountType"/>
<xsd:complexType name="BillToAccountType">
<xsd:complexContent>
<xsd:extension base="tns:TenderType">
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="0" name="accountId" type="xsd:long"/>
<xsd:element maxOccurs="1" minOccurs="0" name="subscriptionId" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="chargeDescription" type="xsd:string"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
And data.xml as:
<?xml version="1.0" encoding="UTF-8"?>
<AddInsuranceToOrderForm xmlns="http://www.example.com/xml-namespace/">
<OrderId>1</OrderId>
<DistributionChannel>1</DistributionChannel>
<FloatNumber>1</FloatNumber>
<UserId>1</UserId>
<SalesId>1</SalesId>
<TotalDue>1</TotalDue>
<ChangeDue>1</ChangeDue>
<BillToAccount>
<date>2012-10-01T23:59:59</date>
<lineNumber>line 1</lineNumber>
<tenderId>1</tenderId>
<returnTenderId>1</returnTenderId>
<amount>1.2</amount>
<accountId>1</accountId>
<subscriptionId>1</subscriptionId>
<chargeDescription>1</chargeDescription>
</BillToAccount>
</AddInsuranceToOrderForm>
Gives output:
<?xml version="1.0" encoding="UTF-8"?>
<BillToAccount xmlns="http://www.example.com/xml-namespace/">
<date>2012-10-01T23:59:59</date>
<lineNumber>line 1</lineNumber>
<tenderId>1</tenderId>
<returnTenderId>1</returnTenderId>
<amount>1.2</amount>
<accountId>1</accountId>
<subscriptionId>1</subscriptionId>
<chargeDescription>1</chargeDescription>
</BillToAccount>
You can't put choice tag inside the all tag. So, is there any workaround to get this functionallity?
For example, I have<settings> tag like:
<settings>
<logging />
<sending />
<useonly />
</settings>
Or something like
<settings>
<logging />
<notuseonly />
<sending />
</settings>
So I want to prevent <useonly> and <notuseonly> showing up together, while the order is not important. And if allowed, in XSD it would look like:
<xs:all>
<xs:element minOccurs="0" maxOccurs="1" ref="sending" />
<xs:element minOccurs="0" maxOccurs="1" ref="logging" />
<xs:choice>
<xs:element minOccurs="0" maxOccurs="1" ref ="useonly" />
<xs:element minOccurs="0" maxOccurs="1" ref ="notuseonly" />
</xs:choice>
</xs:all>
Any thoughts?
Check this link: http://www.w3.org/wiki/Needs_choice_inside_all
I summarize for you the solutions proposed:
One solution is to wrap the element that can change inside another:
<xsd:all>
<xsd:element minOccurs="0" maxOccurs="1" ref="sending" />
<xsd:element minOccurs="0" maxOccurs="1" ref="logging"/>
<xsd:element minOccurs="0" maxOccurs="1" ref ="usetype"/>
</xsd:all>
<xsd:element name="usetype">
<xsd:complexType>
<xsd:choice>
<xsd:element ref="useonly"/>
<xsd:element ref="notuseonly"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
The other one is to use a substitution group:
<xsd:all>
<xsd:element ref="sending"/>
<xsd:element ref="logging"/>
<xsd:element ref="usetype"/>
</xsd:all>
</xsd:complexType>
<xsd:element name="usetype" abstract="true"/>
<xsd:element name="useonly" substitutionGroup="usetype"> ... </xsd:element>
<xsd:element name="notuseonly" substitutionGroup="usetype"> ... </xsd:element>
I am using xsd:schema which will be used to generated desired xml, I have a title field in xsd:schema.
I want to validate it from xsd:schema only that whenever user try to put values more than 10 characters, it will generate the error.
Below is the part of my xsd:schema
<xsd:sequence>
<xsd:element name="Title" minOccurs="0" maxOccurs="1" type="xsd:normalizedString"/>
<xsd:element name="City" minOccurs="0" maxOccurs="1" type="tcmi:SimpleLink">
<xsd:annotation>
<xsd:appinfo>
<tcm:linktype>ComponentLink</tcm:linktype>
<tcm:AllowMultimediaLinks>false</tcm:AllowMultimediaLinks>
<tcm:AllowedTargetSchemas>
<tcm:TargetSchema xlink:href="tcm:227-190428-8" xlink:title="City"/>
</tcm:AllowedTargetSchemas>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="FlightLinkText" minOccurs="0" maxOccurs="1" type="xsd:normalizedString"/>
</xsd:sequence>
I means that can we validate it from <xsd:element name="Title" minOccurs="0" maxOccurs="1" type="xsd:normalizedString"/>
Please suggest!
Have you tried something like:
<xsd:element name="Title" minOccurs="0" maxOccurs="1">
<xsd:simpleType>
<xsd:restriction base="xsd:normalizedString">
<xsd:maxLength value="10"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>