在OpenXML中应用数字格式

我试图从头开始使用OpenXML创build一个Excel电子表格,我已经得到了一切工作正常(倾倒实际的单元格的实际值),但现在我试图将数字格式应用到列,我遇到了一个问题。 我有styles.xml如下所示:

 <?xml version="1.0" encoding="utf-8"?> <x:styleSheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> <x:numFmts count="12"> <x:numFmt numFmtId="216" formatCode="#,###" /> <x:numFmt numFmtId="217" formatCode="$#,###" /> <x:numFmt numFmtId="218" formatCode="#0.00" /> <x:numFmt numFmtId="219" formatCode="#,###" /> <x:numFmt numFmtId="220" formatCode="#0.0%" /> <x:numFmt numFmtId="221" formatCode="#,###" /> <x:numFmt numFmtId="222" formatCode="#0.0%" /> <x:numFmt numFmtId="223" formatCode="#0.0%" /> <x:numFmt numFmtId="224" formatCode="#0.0%" /> <x:numFmt numFmtId="225" formatCode="#,###" /> <x:numFmt numFmtId="226" formatCode="#,###" /> <x:numFmt numFmtId="227" formatCode="#0.0%" /> </x:numFmts> <x:cellXfs count="12"> <x:xf numFmtId="216" applyNumberFormat="1" /> <x:xf numFmtId="217" applyNumberFormat="1" /> <x:xf numFmtId="218" applyNumberFormat="1" /> <x:xf numFmtId="219" applyNumberFormat="1" /> <x:xf numFmtId="220" applyNumberFormat="1" /> <x:xf numFmtId="221" applyNumberFormat="1" /> <x:xf numFmtId="222" applyNumberFormat="1" /> <x:xf numFmtId="223" applyNumberFormat="1" /> <x:xf numFmtId="224" applyNumberFormat="1" /> <x:xf numFmtId="225" applyNumberFormat="1" /> <x:xf numFmtId="226" applyNumberFormat="1" /> <x:xf numFmtId="227" applyNumberFormat="1" /> </x:cellXfs> </x:styleSheet> 

但Excel似乎并不喜欢它,并在“修复”文件后将其删除。 我在这里错过了什么? 这些文档在保持Excel快乐所需要的东西方面有一点点缺陷。

我手动分配的numFmtId开始我认为可能是一个适当的高数字。 这是正确的做法吗?

此外,我意识到formatCode是重复的,但我认为Excel不会被绊倒,我可以巩固他们,如果有必要。

我的列定义如下所示(在sheet.xml ):

 <x:cols> <x:col min="1" max="1" width="7" /> <x:col min="2" max="2" width="58" /> <x:col min="3" max="3" width="16" style="0" /> <x:col min="4" max="4" width="6" style="1" /> <x:col min="5" max="5" width="17" style="2" /> <x:col min="6" max="6" width="16" style="3" /> <x:col min="7" max="7" width="18" style="4" /> <x:col min="8" max="8" width="17" style="5" /> <x:col min="9" max="9" width="20" style="6" /> <x:col min="10" max="10" width="21" style="7" /> <x:col min="11" max="11" width="21" style="8" /> <x:col min="12" max="12" width="16" style="9" /> <x:col min="13" max="13" width="16" style="10" /> <x:col min="14" max="14" width="19" style="11" /> </x:cols> 

为了比较 – 下面是由Excel本身创build的工作styles.xml文件的一个片段:

 <numFmts count="1"> <numFmt numFmtId="164" formatCode="#,##0\p"/> // where does 164 come from? </numFmts> <cellXfs count="3"> <xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/> // do you always need a 0 xf entry? It isn't referenced in the sheet.xml file <xf numFmtId="3" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/> // assuming numFmtId = 3 is a built in format?? <xf numFmtId="164" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/> </cellXfs> 

回答我自己的问题,但我碰到这个职位:

http://polymathprogrammer.com/2009/11/09/how-to-create-stylesheet-in-excel-open-xml/

这表明最小的样式表需要比numFmtscellXfs更多的东西。 所以,我调整了他们的代码来生成一个最小的样式表,为我准备好插入我的单元格格式和数字格式(我正在循环中):

  private Stylesheet CreateStylesheet() { Stylesheet ss = new Stylesheet(); Fonts fts = new Fonts(); DocumentFormat.OpenXml.Spreadsheet.Font ft = new DocumentFormat.OpenXml.Spreadsheet.Font() { FontName = new FontName() { Val = "Calibri" }, FontSize = new FontSize() { Val = 11 } }; fts.Append(ft); fts.Count = (uint)fts.ChildElements.Count; Fills fills = new Fills(); fills.Append(new Fill() { PatternFill = new PatternFill() { PatternType = PatternValues.None } }); fills.Append(new Fill() { PatternFill = new PatternFill() { PatternType = PatternValues.Gray125 } }); fills.Count = (uint)fills.ChildElements.Count; Borders borders = new Borders(); Border border = new Border() { LeftBorder = new LeftBorder(), RightBorder = new RightBorder(), TopBorder = new TopBorder(), BottomBorder = new BottomBorder(), DiagonalBorder = new DiagonalBorder() }; borders.Append(border); borders.Count = (uint)borders.ChildElements.Count; CellStyleFormats csfs = new CellStyleFormats(); CellFormat cf = new CellFormat() { NumberFormatId = 0, FontId = 0, FillId = 0, BorderId = 0 }; csfs.Append(cf); csfs.Count = (uint)csfs.ChildElements.Count; NumberingFormats nfs = new NumberingFormats(); CellFormats cfs = new CellFormats(); cf = new CellFormat() { NumberFormatId = 0, FontId = 0, FillId = 0, BorderId = 0, FormatId = 0 }; cfs.Append(cf); ss.Append(nfs); ss.Append(fts); ss.Append(fills); ss.Append(borders); ss.Append(csfs); ss.Append(cfs); CellStyles css = new CellStyles(); CellStyle cs = new CellStyle() { Name = "Normal", FormatId = 0, BuiltinId = 0 }; css.Append(cs); css.Count = (uint)css.ChildElements.Count; ss.Append(css); DifferentialFormats dfs = new DifferentialFormats(); dfs.Count = 0; ss.Append(dfs); TableStyles tss = new TableStyles() { Count = 0, DefaultTableStyle = "TableStyleMedium9", DefaultPivotStyle = "PivotStyleLight16" }; ss.Append(tss); return ss; } 

不是肯定的,那里没有东西可以放弃,但是我没有耐心通过反复试验来看它是否可以变得更苗条。

我猜想一个单元FormatId除了NumberFormatId之外还必须有一个FontIdFillIdBorderIdFormatId ,为了获得这些ID,你至less需要为它们创build一个条目。 尽pipeXML Schema将它们标记为“可选”。