C# OpenXML:未应用数字格式

C# OpenXML: Number Format is not applied

我正在尝试在我的 .xlsx 文件中格式化小数和整数,例如“1,000.00”。

生成样式表的代码:

private Stylesheet GenerateStylesheet()
{
    //styling and formatting
    var cellFormats = new CellFormats();
    uint iExcelIndex = 164;

    //number formats
    var numericFormats = new NumberingFormats();
    var nformat4Decimal = new NumberingFormat
    {
        NumberFormatId = UInt32Value.FromUInt32(iExcelIndex++),
        FormatCode = StringValue.FromString("#,##0.00")
    };
    numericFormats.Append(nformat4Decimal);    

    //cell formats
    var cellFormat = new CellFormat
    {
        NumberFormatId = nformat4Decimal.NumberFormatId,
        FontId = 0,
        FillId = 0,
        BorderId = 0,
        FormatId = 0,
        ApplyNumberFormat = BooleanValue.FromBoolean(true)
    };
    cellFormats.Append(cellFormat);

    numericFormats.Count = UInt32Value.FromUInt32((uint)numericFormats.ChildElements.Count);
    cellFormats.Count = UInt32Value.FromUInt32((uint)cellFormats.ChildElements.Count);

    var stylesheet = new Stylesheet();
    stylesheet.Append(numericFormats);

    return stylesheet;
}

向文档添加样式表的代码:

WorkbookStylesPart stylesPart = workbookpart.AddNewPart<WorkbookStylesPart>();
stylesPart.Stylesheet = GenerateStylesheet();
stylesPart.Stylesheet.Save();

单元格是这样生成的:

var numberCell = new Cell
{
    DataType = CellValues.Number,
    CellReference = header + index,
    CellValue = new CellValue(text),
    StyleIndex = 0
};

通过 OpenXML 生产力工具,我可以看到那里有数字样式,它是 "applied" 到单元格。




但是当打开单元格中生成的文档值时,格式不符合预期。

此外,我发现 #,##0.00 是 ID = 4 的默认 Excel 格式之一。但是将 NumberFormatId = nformat4Decimal.NumberFormatId 更改为 NumberFormatId = 4 没有任何影响。

正如它发现的那样,您不能只输入数字格式。您必须指定字体、填充、边框。完成该数字格式后,finnaly 得到了应用。 结束这个:

private static Stylesheet GenerateStylesheet2()
{
    Stylesheet ss = new Stylesheet();

    Fonts fts = new Fonts();
    DocumentFormat.OpenXml.Spreadsheet.Font ft = new DocumentFormat.OpenXml.Spreadsheet.Font();
    FontName ftn = new FontName();
    ftn.Val = "Calibri";
    FontSize ftsz = new FontSize();
    ftsz.Val = 11;
    ft.FontName = ftn;
    ft.FontSize = ftsz;
    fts.Append(ft);
    fts.Count = (uint)fts.ChildElements.Count;

    Fills fills = new Fills();
    Fill fill;
    PatternFill patternFill;
    fill = new Fill();
    patternFill = new PatternFill();
    patternFill.PatternType = PatternValues.None;
    fill.PatternFill = patternFill;
    fills.Append(fill);
    fill = new Fill();
    patternFill = new PatternFill();
    patternFill.PatternType = PatternValues.Gray125;
    fill.PatternFill = patternFill;
    fills.Append(fill);
    fills.Count = (uint)fills.ChildElements.Count;

    Borders borders = new Borders();
    Border border = new Border();
    border.LeftBorder = new LeftBorder();
    border.RightBorder = new RightBorder();
    border.TopBorder = new TopBorder();
    border.BottomBorder = new BottomBorder();
    border.DiagonalBorder = new DiagonalBorder();
    borders.Append(border);
    borders.Count = (uint)borders.ChildElements.Count;

    CellStyleFormats csfs = new CellStyleFormats();
    CellFormat cf = new CellFormat();
    cf.NumberFormatId = 0;
    cf.FontId = 0;
    cf.FillId = 0;
    cf.BorderId = 0;
    csfs.Append(cf);
    csfs.Count = (uint)csfs.ChildElements.Count;

    uint iExcelIndex = 164;
    NumberingFormats nfs = new NumberingFormats();
    CellFormats cfs = new CellFormats();

    cf = new CellFormat();
    cf.NumberFormatId = 0;
    cf.FontId = 0;
    cf.FillId = 0;
    cf.BorderId = 0;
    cf.FormatId = 0;
    cfs.Append(cf);

    NumberingFormat nf;
    nf = new NumberingFormat();
    nf.NumberFormatId = iExcelIndex++;
    nf.FormatCode = "dd/mm/yyyy hh:mm:ss";
    nfs.Append(nf);
    cf = new CellFormat();
    cf.NumberFormatId = nf.NumberFormatId;
    cf.FontId = 0;
    cf.FillId = 0;
    cf.BorderId = 0;
    cf.FormatId = 0;
    cf.ApplyNumberFormat = true;
    cfs.Append(cf);

    nf = new NumberingFormat();
    nf.NumberFormatId = iExcelIndex++;
    nf.FormatCode = "#,##0.0000";
    nfs.Append(nf);
    cf = new CellFormat();
    cf.NumberFormatId = nf.NumberFormatId;
    cf.FontId = 0;
    cf.FillId = 0;
    cf.BorderId = 0;
    cf.FormatId = 0;
    cf.ApplyNumberFormat = true;
    cfs.Append(cf);

    // #,##0.00 is also Excel style index 4
    nf = new NumberingFormat();
    nf.NumberFormatId = iExcelIndex++;
    nf.FormatCode = "#,##0.00";
    nfs.Append(nf);
    cf = new CellFormat();
    cf.NumberFormatId = nf.NumberFormatId;
    cf.FontId = 0;
    cf.FillId = 0;
    cf.BorderId = 0;
    cf.FormatId = 0;
    cf.ApplyNumberFormat = true;
    cfs.Append(cf);

    // @ is also Excel style index 49
    nf = new NumberingFormat();
    nf.NumberFormatId = iExcelIndex++;
    nf.FormatCode = "@";
    nfs.Append(nf);
    cf = new CellFormat();
    cf.NumberFormatId = nf.NumberFormatId;
    cf.FontId = 0;
    cf.FillId = 0;
    cf.BorderId = 0;
    cf.FormatId = 0;
    cf.ApplyNumberFormat = true;
    cfs.Append(cf);

    nfs.Count = (uint)nfs.ChildElements.Count;
    cfs.Count = (uint)cfs.ChildElements.Count;

    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();
    cs.Name = "Normal";
    cs.FormatId = 0;
    cs.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();
    tss.Count = 0;
    tss.DefaultTableStyle = "TableStyleMedium9";
    tss.DefaultPivotStyle = "PivotStyleLight16";
    ss.Append(tss);

    return ss;
}

对于单元格创建:

var numberCell = new Cell
{
    DataType = CellValues.Number,
    CellReference = header + index,
    CellValue = new CellValue(text),
    StyleIndex = 3
};

样式索引3引用了数字格式"#,##0.00"的单元格样式。