/** * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at the * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Initial code contributed and copyrighted by<br> * frentix GmbH, http://www.frentix.com * <p> */ package org.olat.core.util.openxml; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import org.apache.commons.io.IOUtils; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; import org.olat.core.util.openxml.workbookstyle.Border; import org.olat.core.util.openxml.workbookstyle.CellStyle; import org.olat.core.util.openxml.workbookstyle.Fill; import org.olat.core.util.openxml.workbookstyle.Font; /** * * Initial date: 21.04.2016<br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ public class OpenXMLWorkbook implements Closeable { private static final OLog log = Tracing.createLoggerFor(OpenXMLWorkbook.class); public static final String SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships"; private static final String SCHEMA_CONTENT_TYPES = "http://schemas.openxmlformats.org/package/2006/content-types"; private static final String SCHEMA_CORE_PROPERTIES = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"; private static final String SCHEMA_EXT_PROPERTIES = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"; private static final String SCHEMA_DOC_PROPS_VT = "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"; private static final String SCHEMA_DC_TERMS = "http://purl.org/dc/terms/"; private static final String SCHEMA_DC = "http://purl.org/dc/elements/1.1/"; private static final String CT_RELATIONSHIP = "application/vnd.openxmlformats-package.relationships+xml"; private static final String CT_EXT_PROPERTIES = "application/vnd.openxmlformats-officedocument.extended-properties+xml"; private static final String CT_CORE_PROPERTIES = "application/vnd.openxmlformats-package.core-properties+xml"; private List<OpenXMLWorksheet> worksheets = new ArrayList<>(10); private final OpenXMLWorkbookStyles styles = new OpenXMLWorkbookStyles(); private OpenXMLWorkbookSharedStrings sharedStrings = new OpenXMLWorkbookSharedStrings(); private int currentId = 4; private boolean opened; private final ZipOutputStream zout; private final int numberOfWorksheet; private OpenXMLWorksheet currentWorkSheet; public OpenXMLWorkbook(OutputStream outputStream, int numberOfWorksheet) { zout = new ZipOutputStream(outputStream); zout.setLevel(9); this.numberOfWorksheet = numberOfWorksheet; for(int i=0; i<numberOfWorksheet; i++) { worksheets.add(new OpenXMLWorksheet(generateId(), this, zout)); } } public int getNumberOfWorksheets() { return numberOfWorksheet; } public OpenXMLWorksheet nextWorksheet() { try { if(!opened) { appendPrologue(); opened = true; } int index = 0; if(currentWorkSheet == null) { currentWorkSheet = worksheets.get(0); } else { currentWorkSheet.close(); zout.closeEntry(); index = worksheets.indexOf(currentWorkSheet) + 1; currentWorkSheet = worksheets.get(index); } ZipEntry worksheetEntry = new ZipEntry("xl/worksheets/sheet" + (index + 1) + ".xml"); zout.putNextEntry(worksheetEntry); return currentWorkSheet; } catch (IOException e) { log.error("", e); return null; } } @Override public void close() throws IOException { if(opened) { currentWorkSheet.close(); zout.closeEntry(); appendEpilogue(); zout.flush(); zout.close(); } } public OpenXMLWorkbookStyles getStyles() { return styles; } public OpenXMLWorkbookSharedStrings getSharedStrings() { return sharedStrings; } private String generateId() { return "rId" + (++currentId); } private final void appendPrologue() { try { //_rels zout.putNextEntry(new ZipEntry("_rels/.rels")); appendShadowDocumentRelationships(); zout.closeEntry(); //[Content_Types].xml zout.putNextEntry(new ZipEntry("[Content_Types].xml")); appendContentTypes(); zout.closeEntry(); //docProps/app.xml zout.putNextEntry(new ZipEntry("docProps/app.xml")); appendDocPropsApp(zout); zout.closeEntry(); //docProps/core.xml zout.putNextEntry(new ZipEntry("docProps/core.xml")); appendDocPropsCore(zout); zout.closeEntry(); //xl/_rels/workbook.xml.rels zout.putNextEntry(new ZipEntry("xl/_rels/workbook.xml.rels")); appendWorkbookRelationships(); zout.closeEntry(); //xl/theme/theme1.xml zout.putNextEntry(new ZipEntry("xl/theme/theme1.xml")); try(InputStream in = OpenXMLDocumentWriter.class.getResourceAsStream("_resources/theme1.xml")) { IOUtils.copy(in, zout); } catch (IOException e) { log.error("", e); } zout.closeEntry(); //xl/workbook.xml zout.putNextEntry(new ZipEntry("xl/workbook.xml")); appendWorkbook(); zout.closeEntry(); } catch (IOException e) { log.error("", e); } } private void appendEpilogue() { try { //xl/styles zout.putNextEntry(new ZipEntry("xl/styles.xml")); appendPredefinedStyles(); zout.closeEntry(); //xl/sharedStrings.xml if(getSharedStrings().size() > 0) { zout.putNextEntry(new ZipEntry("xl/sharedStrings.xml")); appendSharedString(); zout.closeEntry(); } } catch (IOException e) { log.error("", e); } } /* <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml" /> <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml" /> <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml" /> </Relationships> */ private final void appendShadowDocumentRelationships() { try { XMLStreamWriter writer = OpenXMLUtils.createStreamWriter(zout); writer.writeStartDocument("UTF-8", "1.0"); writer.writeStartElement("Relationships"); writer.writeNamespace("", SCHEMA_RELATIONSHIPS); addRelationship("rId1", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", "xl/workbook.xml", writer); addRelationship("rId2", "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties", "docProps/core.xml", writer); addRelationship("rId3", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties", "docProps/app.xml", writer); writer.writeEndElement();// end Relationships writer.writeEndDocument(); writer.flush(); writer.close(); } catch (XMLStreamException e) { log.error("", e); } } private final void addRelationship(String id, String type, String target, XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement("Relationship"); writer.writeAttribute("Id", id); writer.writeAttribute("Type", type); writer.writeAttribute("Target", target); writer.writeEndElement(); } /* <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> <Default Extension="xml" ContentType="application/xml" /> <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" /> <Default Extension="jpeg" ContentType="image/jpeg" /> <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" /> <Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml" /> <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" /> <Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml" /> <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml" /> <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" /> <Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" /> </Types> */ protected void appendContentTypes() { try { XMLStreamWriter writer = OpenXMLUtils.createStreamWriter(zout); writer.writeStartDocument("UTF-8", "1.0"); writer.writeStartElement("Types"); writer.writeNamespace("", SCHEMA_CONTENT_TYPES); //Default createContentTypesDefault("rels", CT_RELATIONSHIP, writer); createContentTypesDefault("xml", "application/xml", writer); createContentTypesDefault("jpeg", "image/jpeg", writer); createContentTypesDefault("jpg", "image/jpeg", writer); createContentTypesDefault("png", "image/png", writer); createContentTypesDefault("gif", "image/gif", writer); //Override createContentTypesOverride("/docProps/app.xml", CT_EXT_PROPERTIES, writer); createContentTypesOverride("/docProps/core.xml", CT_CORE_PROPERTIES, writer); //Override workbook createContentTypesOverride("/xl/workbook.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", writer); createContentTypesOverride("/xl/theme/theme1.xml", "application/vnd.openxmlformats-officedocument.theme+xml", writer); createContentTypesOverride("/xl/styles.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml", writer); if(getSharedStrings().size() > 0) { createContentTypesOverride("/xl/sharedStrings.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml", writer); } //Override worksheets for(int i=0; i<getNumberOfWorksheets(); i++) { createContentTypesOverride("/xl/worksheets/sheet" + (i+1) + ".xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml", writer); } writer.writeEndElement();// end Types writer.flush(); writer.close(); } catch (XMLStreamException e) { log.error("", e); } } private final void createContentTypesDefault(String extension, String type, XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement("Default"); writer.writeAttribute("Extension", extension); writer.writeAttribute("ContentType", type); writer.writeEndElement(); } private final void createContentTypesOverride(String partName, String type, XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement("Override"); writer.writeAttribute("PartName", partName); writer.writeAttribute("ContentType", type); writer.writeEndElement(); } /* <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"> <Application> Microsoft Macintosh Excel </Application> <DocSecurity> 0 </DocSecurity> <ScaleCrop> false </ScaleCrop> <HeadingPairs> <vt:vector size="2" baseType="variant"> <vt:variant> <vt:lpstr> Arbeitsblätter </vt:lpstr> </vt:variant> <vt:variant> <vt:i4> 1 </vt:i4> </vt:variant> </vt:vector> </HeadingPairs> <TitlesOfParts> <vt:vector size="1" baseType="lpstr"> <vt:lpstr>Blatt1 </vt:lpstr> </vt:vector> </TitlesOfParts> <Company> frentix </Company> <LinksUpToDate> false </LinksUpToDate> <SharedDoc> false </SharedDoc> <HyperlinksChanged> false </HyperlinksChanged> <AppVersion> 14.0300 </AppVersion> </Properties> */ private static final void appendDocPropsApp(ZipOutputStream out) { try { XMLStreamWriter writer = OpenXMLUtils.createStreamWriter(out); writer.writeStartDocument("UTF-8", "1.0"); writer.writeStartElement("Properties"); writer.writeNamespace("", SCHEMA_EXT_PROPERTIES); writer.writeNamespace("vt", SCHEMA_DOC_PROPS_VT); appendTag("Application", "Microsoft Macintosh Excel", writer); appendTag("DocSecurity", "0", writer); appendTag("ScaleCrop", "false", writer); //HeadingPairs writer.writeStartElement("HeadingPairs"); writer.writeStartElement("vt:vector"); writer.writeAttribute("size", "2"); writer.writeAttribute("baseType", "variant"); //1 variant writer.writeStartElement("vt:variant"); appendTag("vt:lpstr", "Arbeitsblätter", writer); writer.writeEndElement(); //2 variant writer.writeStartElement("vt:variant"); appendTag("vt:i4", "1", writer); writer.writeEndElement(); writer.writeEndElement(); writer.writeEndElement();// end HeadingPairs //TitlesOfParts writer.writeStartElement("TitlesOfParts"); writer.writeStartElement("vt:vector"); writer.writeAttribute("size", "1");//TODO writer.writeAttribute("baseType", "lpstr");//TODO writer.writeStartElement("vt:lpstr"); writer.writeCharacters("Sheet 1"); writer.writeEndElement(); writer.writeEndElement(); writer.writeEndElement();// end TitlesOfParts appendTag("Company", "frentix", writer); appendTag("LinksUpToDate", "false", writer); appendTag("SharedDoc", "false", writer); appendTag("HyperlinksChanged", "false", writer); appendTag("AppVersion", "14.0300", writer); writer.writeEndElement();// end properties writer.flush(); writer.close(); } catch (XMLStreamException e) { log.error("", e); } } /* <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <dc:creator> Stéphane Rossé </dc:creator> <cp:lastModifiedBy> Stéphane Rossé </cp:lastModifiedBy> <dcterms:created xsi:type="dcterms:W3CDTF"> 2016-04-21T14:56:49Z </dcterms:created> <dcterms:modified xsi:type="dcterms:W3CDTF"> 2016-04-21T15:03:56Z </dcterms:modified> </cp:coreProperties> */ private static final void appendDocPropsCore(ZipOutputStream out) { try { XMLStreamWriter writer = OpenXMLUtils.createStreamWriter(out); writer.writeStartDocument("UTF-8", "1.0"); writer.writeStartElement("cp:coreProperties"); writer.writeNamespace("cp", SCHEMA_CORE_PROPERTIES); writer.writeNamespace("dc", SCHEMA_DC); writer.writeNamespace("dcterms", SCHEMA_DC_TERMS); writer.writeNamespace("dcmitype", "http://purl.org/dc/dcmitype/"); writer.writeNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); writer.writeStartElement("dc:creator"); writer.writeCharacters("OpenOLAT"); writer.writeEndElement(); writer.writeStartElement("cp:lastModifiedBy"); writer.writeCharacters("OpenOLAT"); writer.writeEndElement(); writer.writeEndElement();// end sst writer.flush(); writer.close(); } catch (XMLStreamException e) { log.error("", e); } } /* <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml" /> <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml" /> <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml" /> <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml" /> </Relationships> */ private final void appendWorkbookRelationships() { try { XMLStreamWriter writer = OpenXMLUtils.createStreamWriter(zout); writer.writeStartDocument("UTF-8", "1.0"); writer.writeStartElement("Relationships"); writer.writeNamespace("", SCHEMA_RELATIONSHIPS); addRelationship("rId1", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles", "styles.xml", writer); if(getSharedStrings().size() > 0) { addRelationship("rId2", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings", "sharedStrings.xml", writer); } addRelationship("rId3", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", "theme/theme1.xml", writer); for(int i=0; i<getNumberOfWorksheets(); i++) { OpenXMLWorksheet worksheet = worksheets.get(i); addRelationship(worksheet.getId(), "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet", "worksheets/sheet" + (i+1) + ".xml", writer); } writer.writeEndElement();// end Relationships writer.writeEndDocument(); writer.flush(); writer.close(); } catch (XMLStreamException e) { log.error("", e); } } /* <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"> <fileVersion appName="xl" lastEdited="5" lowestEdited="5" rupBuild="25823" /><workbookPr showInkAnnotation="0" autoCompressPictures="0" /> <bookViews> <workbookView xWindow="5060" yWindow="2060" windowWidth="25600" windowHeight="19020" tabRatio="500" /> </bookViews> <sheets> <sheet name="Blatt1" sheetId="1" r:id="rId1" /> </sheets> <calcPr calcId="140000" concurrentCalc="0" /> <extLst> <ext uri="{7523E5D3-25F3-A5E0-1632-64F254C22452}" xmlns:mx="http://schemas.microsoft.com/office/mac/excel/2008/main"> <mx:ArchID Flags="2" /> </ext> </extLst> </workbook> */ private void appendWorkbook() { try { XMLStreamWriter writer = OpenXMLUtils.createStreamWriter(zout); writer.writeStartDocument("UTF-8", "1.0"); writer.writeStartElement("workbook"); writer.writeNamespace("", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); writer.writeNamespace("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships"); //fileVersion writer.writeStartElement("fileVersion"); writer.writeAttribute("appName", "xl"); writer.writeAttribute("lastEdited", "1"); writer.writeAttribute("lowestEdited", "1"); writer.writeAttribute("rupBuild", "25823"); writer.writeEndElement(); //workbookPr writer.writeStartElement("workbookPr"); writer.writeAttribute("showInkAnnotation", "0"); writer.writeAttribute("autoCompressPictures", "0"); writer.writeEndElement(); //bookViews / workbookView writer.writeStartElement("bookViews"); writer.writeStartElement("workbookView"); writer.writeAttribute("xWindow", "5060"); writer.writeAttribute("yWindow", "2060"); writer.writeAttribute("windowWidth", "25600"); writer.writeAttribute("windowHeight", "19020"); writer.writeAttribute("tabRatio", "500"); writer.writeEndElement(); writer.writeEndElement(); //sheets writer.writeStartElement("sheets"); int count = 1; for(OpenXMLWorksheet sheet:worksheets) { writer.writeStartElement("sheet"); writer.writeAttribute("name", "Sheet " + count); writer.writeAttribute("sheetId", Integer.toString(count++)); writer.writeAttribute("r:id", sheet.getId()); writer.writeEndElement(); } writer.writeEndElement(); //workbookPr writer.writeStartElement("calcPr"); writer.writeAttribute("calcId", "140000"); writer.writeAttribute("concurrentCalc", "0"); writer.writeEndElement(); //extLst writer.writeStartElement("extLst"); writer.writeStartElement("ext"); writer.writeAttribute("uri", "{7523E5D3-25F3-A5E0-1632-64F254C22452}"); writer.writeNamespace("mx", "http://schemas.microsoft.com/office/mac/excel/2008/main"); writer.writeStartElement("ext"); writer.writeStartElement("mx:ArchID"); writer.writeAttribute("Flags", "2"); writer.writeEndElement(); writer.writeEndElement(); writer.writeEndElement(); writer.writeEndElement(); writer.writeEndElement();// end workbook writer.flush(); writer.close(); } catch (XMLStreamException e) { log.error("", e); } } /* <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"> <fonts count="1" x14ac:knownFonts="1"/> <fills count="4"/> <borders count="2"/> <cellStyleXfs count="1"/> <cellXfs count="5"/> <cellStyles count="1"> <cellStyle name="Standard" xfId="0" builtinId="0" /> </cellStyles> <dxfs count="0" /><tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleMedium4" /> </styleSheet> */ private void appendPredefinedStyles() { try { XMLStreamWriter writer = OpenXMLUtils.createStreamWriter(zout); writer.writeStartDocument("UTF-8", "1.0"); writer.writeStartElement("styleSheet"); writer.writeNamespace("", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); writer.writeNamespace("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006"); writer.writeAttribute("mc:Ignorable", "x14ac"); writer.writeNamespace("x14ac", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"); appendFonts(styles.getFonts(), writer); appendFills(styles.getFills(), writer); appendBorders(styles.getBorders(), writer); //cellStyleXfs writer.writeStartElement("cellStyleXfs"); writer.writeAttribute("count", "1"); writer.writeStartElement("xf"); writer.writeAttribute("numFmtId", "0"); writer.writeAttribute("fontId", "0"); writer.writeAttribute("fillId", "0"); writer.writeAttribute("borderId", "0"); writer.writeEndElement(); writer.writeEndElement(); //cellXfs appendCellXfs(styles.getCellXfs(), writer); //cellStyles writer.writeStartElement("cellStyles"); writer.writeAttribute("count", "1"); writer.writeStartElement("cellStyle"); writer.writeAttribute("name", "Standard"); writer.writeAttribute("xfId", "0"); writer.writeAttribute("builtinId", "0"); writer.writeEndElement(); writer.writeEndElement(); //dxfs writer.writeStartElement("dxfs"); writer.writeAttribute("count", "0"); writer.writeEndElement(); //tableStyles writer.writeStartElement("tableStyles"); writer.writeAttribute("count", "0"); writer.writeAttribute("defaultTableStyle", "TableStyleMedium9"); writer.writeAttribute("defaultPivotStyle", "PivotStyleMedium4"); writer.writeEndElement(); writer.writeEndElement();// end sst writer.flush(); writer.close(); } catch (XMLStreamException e) { log.error("", e); } } /* <cellXfs count="5"> <xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0" /> <xf numFmtId="0" fontId="0" fillId="2" borderId="0" xfId="0" applyFill="1" /> <xf numFmtId="0" fontId="0" fillId="3" borderId="0" xfId="0" applyFill="1" /> <xf numFmtId="14" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1" /> <xf numFmtId="0" fontId="0" fillId="0" borderId="1" xfId="0" applyBorder="1" /> </cellXfs> */ private void appendCellXfs(List<CellStyle> cellXfs, XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement("cellXfs"); writer.writeAttribute("count", Integer.toString(cellXfs.size())); for (CellStyle style: cellXfs) { appendCellXfs(style, writer); } writer.writeEndElement(); } private void appendCellXfs(CellStyle style, XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement("xf"); writer.writeAttribute("numFmtId", style.getNumFmtId()); writer.writeAttribute("fontId", Integer.toString(style.getFont().getIndex())); writer.writeAttribute("fillId", Integer.toString(style.getFill().getIndex())); writer.writeAttribute("borderId", Integer.toString(style.getBorder().getIndex())); writer.writeAttribute("xfId", style.getId()); if(style.getBorder().getIndex() > 0) { writer.writeAttribute("applyBorder", "1"); } if(style.getFill().getIndex() > 0) { writer.writeAttribute("applyFill", "1"); } if(StringHelper.containsNonWhitespace(style.getApplyNumberFormat())) { writer.writeAttribute("applyNumberFormat", style.getApplyNumberFormat()); } writer.writeEndElement(); } /* <font> <sz val="12" /> <color theme="1" /> <name val="Calibri" /> <family val="2" /> <scheme val="minor" /> </font> */ private void appendFonts(List<Font> fonts, XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement("fonts"); writer.writeAttribute("count", Integer.toString(fonts.size())); writer.writeAttribute("x14ac:knownFonts", Integer.toString(fonts.size())); for (Font font: fonts) { writer.writeStartElement("font"); appendTag("sz", "val", font.getSzVal(), writer); appendTag("color", "theme", font.getColorTheme(), writer); appendTag("name", "val", font.getNameVal(), writer); appendTag("family", "val", font.getFamilyVal(), writer); appendTag("scheme", "val", font.getSchemeVal(), writer); writer.writeEndElement(); } writer.writeEndElement(); } /* <fill> <patternFill patternType="none" /> </fill> */ private void appendFills(List<Fill> fills, XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement("fills"); writer.writeAttribute("count", Integer.toString(fills.size())); for (Fill fill: fills) { writer.writeStartElement("fill"); if(StringHelper.containsNonWhitespace(fill.getPatternType())) { writer.writeStartElement("patternFill"); writer.writeAttribute("patternType", fill.getPatternType()); if(StringHelper.containsNonWhitespace(fill.getFgColorRgb())) { //<fgColor rgb="FFC3FFC0" /> appendTag("fgColor", "rgb", fill.getFgColorRgb(), writer); } if(StringHelper.containsNonWhitespace(fill.getBgColorIndexed())) { //<bgColor indexed="64" /> appendTag("bgColor", "indexed", fill.getBgColorIndexed(), writer); } writer.writeEndElement(); } writer.writeEndElement(); } writer.writeEndElement(); } /* <border> <left /><right /><top /><bottom /><diagonal /> </border> */ private void appendBorders(List<Border> borders, XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement("borders"); writer.writeAttribute("count", Integer.toString(borders.size())); for (Border border: borders) { writer.writeStartElement("border"); appendBorderLine("left", border.getLeft(), writer); appendBorderLine("right", border.getRight(), writer); appendBorderLine("top", border.getTop(), writer); appendBorderLine("bottom", border.getBottom(), writer); writer.writeEmptyElement("diagonal"); writer.writeEndElement(); } writer.writeEndElement(); } private void appendBorderLine(String position, String value, XMLStreamWriter writer) throws XMLStreamException { if(StringHelper.containsNonWhitespace(value)) { writer.writeStartElement(position); writer.writeAttribute("style", value); appendTag("color", "auto", "1", writer); writer.writeEndElement(); } else { writer.writeEmptyElement(position); } } /* <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4"> <si> <t> Test </t> </si> </sst> */ private void appendSharedString() { try { XMLStreamWriter writer = OpenXMLUtils.createStreamWriter(zout); writer.writeStartDocument("UTF-8", "1.0"); writer.writeStartElement("sst"); writer.writeNamespace("", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); writer.writeAttribute("count", Integer.toString(sharedStrings.size())); writer.writeAttribute("uniqueCount", Integer.toString(sharedStrings.size())); for (String sharedString: sharedStrings) { writer.writeStartElement("si"); writer.writeStartElement("t"); if(sharedString.contains("<") || sharedString.contains(">")) { writer.writeCData(sharedString); } else { writer.writeCharacters(sharedString); } writer.writeEndElement(); writer.writeEndElement(); } writer.writeEndElement();// end sst writer.flush(); writer.close(); } catch (XMLStreamException e) { log.error("", e); } } private static final void appendTag(String tag, String characters, XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement(tag); writer.writeCharacters(characters); writer.writeEndElement(); } private static final void appendTag(String tag, String attribute, String attributeValue, XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement(tag); writer.writeAttribute(attribute, attributeValue); writer.writeEndElement(); } }