【问题标题】:c# open xml reformatting existing cell to a numberc# open xml 将现有单元格重新格式化为数字
【发布时间】:2018-09-19 14:42:16
【问题描述】:

我有一个现有的电子表格。我想将一些单元格从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

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

链接到示例文件

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

【问题讨论】:

  • 请附上您的原始excel文件。
  • @AccessDenied 我该怎么做?
  • 通过 google drive 或 dropbox 或 onedrive 共享它并提供此文件的链接
  • @AccessDenied 刚刚编辑了链接。

标签: c# openxml-sdk


【解决方案1】:

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

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

您会看到您的单元格具有 SharedString 数据类型。它是一种 id,cell 存储 id,而 value 存储在 sharedstring 表中。您在更改日期类型后看到的这些奇怪数字是共享字符串表中的这些 id。 更改 DataType 并不会真正改变值的存储方式,它会改变它们的解释方式。如果您将其类型更改为数字,它们仍将是“数字存储为字符串”。 例如让我们看一下单元格“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 docs 示例中的 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 公式。

【讨论】:

  • 谢谢。我不知道我必须设置 CellValue,即使它已经有一个。它没有计算出来,因为数字是左对齐的。显然,这意味着 excel 将它们视为“数字作为文本”。我认为这些数字正在通过您的 cmets 的SharedStringTable 进行更新。这可能就是为什么当我拿到表格时,数字是左对齐的。
猜你喜欢
  • 1970-01-01
  • 2019-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-12
  • 2011-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多