c# open xml 将现有单元格重新格式化为数字

c# open xml reformatting existing cell to a number

我有一个现有的电子表格。我想将某些单元格从 generalcustom 重新格式化为 Number。但出于某种原因,当我重新格式化它们以编号时,单元格值更改为某个随机数。

这是我的代码的样子

           using (var d = SpreadsheetDocument.Open(_docPath, true))
            {
                var workSheet = GetWorksheetPart(d.WorkbookPart.Workbook.WorkbookPart, "Project Summary");

                foreach (var cellRef in _ProjectRequirementsFormService.NumberCellReferences)
                {
                    Cell theCell = workSheet.Worksheet.Descendants<Cell>().Where(c => c.CellReference == cellRef).FirstOrDefault();
                    if (theCell != null) {
                        //For some reason This line of code replaces the cell value with a value 5197
                        //and every iteration of the loop increments the value of the next cell found 5198, 5199, etc....
                        theCell.DataType = CellValues.Number;
                    }
                }
...
}

    public WorksheetPart GetWorksheetPart(WorkbookPart workbookPart, string sheetName)
    {
        string relId = workbookPart.Workbook.Descendants<Sheet>().First(s => sheetName.Equals(s.Name)).Id;
        return (WorksheetPart)workbookPart.GetPartById(relId);
    }

现在由于某些原因这行代码theCell.DataType = CellValues.Number;将单元格值替换为值 5197 循环的每次迭代都会增加找到的下一个单元格的值 5198、5199 等....

当我评论那条有缺陷的行时,我在单元格中得到了正确的值,但格式不是 Number

这是我添加代码行以将其更改为数字格式时的样子。为什么它会更改所有单元格值,我该如何解决?

Link 到示例文件

https://drive.google.com/file/d/0B7UImeY4gR3VdnBBZmdWSHJqN2lhRmFqY1N6THJXNmIzZDhF/view?usp=sharing

使用 Microsoft Open XML SDK 工具将 xlsx 反编译为 C#。

https://www.microsoft.com/en-us/download/details.aspx?id=30425

您会看到您的单元格具有 SharedString 数据类型。它是一种id,cell存储id,而values存储在sharedstringtable中。您在更改日期类型后看到的这些奇怪的数字是共享字符串 table 中的这些 ID。 更改 DataType 并没有真正改变值的存储方式,它改变了它们的解释方式。如果您将其类型更改为数字,它们仍将是 "Number stored as string"。 例如,让我们看一下单元格 "E17":

Cell cell261 = new Cell(){ CellReference = "E17", StyleIndex = (UInt32Value)11U, DataType = CellValues.SharedString };
CellValue cellValue90 = new CellValue();
cellValue90.Text = "26";

... 应该是 50000 吧?

        SharedStringItem sharedStringItem27 = new SharedStringItem();
        Text text45 = new Text();
        text45.Text = "50000";
        sharedStringItem27.Append(text45);

为了从电子表格中读取正确的值,您需要使用 MS 文档示例中的 GetCellValue 代码。

https://docs.microsoft.com/en-us/office/open-xml/how-to-retrieve-the-values-of-cells-in-a-spreadsheet

然后你可以写下面的代码来读取真实的单元格值(我稍微改变了一下,传递文档而不是文件路径)解析它并保存为十进制类型:

var value = GetCellValue(d, "Sheet1", cellRef.CellReference);

if (!string.IsNullOrEmpty(value))
{
  if (decimal.TryParse(value, out decimal val))
   {
      cellRef.CellValue = new 
      CellValue(DocumentFormat.OpenXml.DecimalValue.FromDecimal(val));
      cellRef.StyleIndex = 0U;                            
   }
 }

StyleIndex 0U 似乎是通用格式,但由于您的单元格类型正确,所以没关系。即使我仍然不明白为什么打开固定 xlsx 时不计算 =sum 公式。