使用Openxml从Excel中读取时,获取浮点数而不是确切的字符串

时间:2018-08-08 07:16:53

标签: c# datatable openxml

我有一个代码可以使用OpenXml将Excel文件读取到数据表中,但是工作正常,但是,当我读取类似“ 7.5”的字符串时,它以浮点格式给出了“ 7.4999999”,为什么会这样呢? 我只想按原样读取它,即在字符串中。因此,“ 7.5”应仅为7.5,而不应为7.499或其他任何值。 任何帮助,将不胜感激。 这是我的数据表中读取Excel的代码

private static string ConvertFileToDataTable(Stream fileStream, DataTable framworkDatatable, List<FileErrorModel> fileErrorModels)
    {
        string frameworkName;

        InitializeDataTable(framworkDatatable);

        using (var document = SpreadsheetDocument.Open(fileStream, true))
        {
            var workbookPart = document.WorkbookPart;

            var mysheet = (Sheet)document.WorkbookPart.Workbook.Sheets.ChildElements.GetItem(0);

            frameworkName = mysheet.Name;

            var worksheet = ((WorksheetPart)workbookPart.GetPartById(mysheet.Id)).Worksheet;

            var sheetData = (SheetData)worksheet.ChildElements.GetItem(4);

            foreach (var row in sheetData.Descendants<Row>())
            {
                if (row == null) continue;
                if (row.RowIndex.Value == Constants.ColumnNameRowIndex)
                {
                    if (row.Descendants<Cell>().Count() > Constants.ValidColumnCount || row.Descendants<Cell>().Count() < Constants.ValidColumnCount)
                    {
                        var error = new FileErrorModel
                        {
                            ErrorText = ValidationMessages.IncompatibleCoulmns,
                            RowNumber = null,
                            ColumnNumber = null
                        };
                        fileErrorModels.Add(error);
                    }
                }

                if (row.RowIndex.Value == Constants.TableNameRowIndex ||
                    row.RowIndex.Value == Constants.ColumnNameRowIndex) continue;

                framworkDatatable.Rows.Add();
                var i = 0;

                foreach (var cell in row.Descendants<Cell>())
                {
                    framworkDatatable.Rows[framworkDatatable.Rows.Count - 1][i] = GetCellValue(document, cell);
                    i++;
                }
            }
        }
        return frameworkName;
    }

这就是我初始化数据表的方式

private static void InitializeDataTable(DataTable framworkDatatable)
    {
        framworkDatatable.Columns.AddRange(new[] {
                new DataColumn(ImportSheetColumnNames.ControlFamilyIdentifier, typeof(string)),
                new DataColumn(ImportSheetColumnNames.ControlFamilyShortName, typeof(string)),
                new DataColumn(ImportSheetColumnNames.ControlFamilyDescription,typeof(string)),
                new DataColumn(ImportSheetColumnNames.ControlIdentifier,typeof(string)),
                new DataColumn(ImportSheetColumnNames.ControlType,typeof(string)),
                new DataColumn(ImportSheetColumnNames.ControlDescription,typeof(string)),
                new DataColumn(ImportSheetColumnNames.TestProcedure,typeof(string)),
                new DataColumn(ImportSheetColumnNames.BestPractice,typeof(string)),
                new DataColumn(ImportSheetColumnNames.Help,typeof(string)),
                new DataColumn(ImportSheetColumnNames.ActionPlan,typeof(string)),
                new DataColumn(ImportSheetColumnNames.Question,typeof(string))
        });
    }

忽略“ ImportSheetColumnNames”,它们只是常量列名

2 个答案:

答案 0 :(得分:0)

简而言之:(二进制)浮点数不能精确表示十进制7.5。没有理由相信您的代码有问题。更多详情,例如此处:Why can't decimal numbers be represented exactly in binary?

答案 1 :(得分:0)

如果在Excel中打开工作表(不是在单元格中,而是在编辑栏中),您会看到什么?

如果我创建一个新的Excel电子表格,然后在相应的单元格中输入以下值:

A1 = 7.5
A2 = 7.4999999
A3 = 7.49  (but formatted to have a single decimal point showing)

我在工作表中看到这三个值均为7.5,但在编辑栏中看到了这三个值。

现在,如果我查看文件(使用Open XML生产力工具-可从Microsoft.com下载,并且对于任何Open XML工作都是必不可少的),则可以在

下看到以下内容保存在文件中
  • 文件名
    • /xl/workbook.xml
      • /xl/worksheets/sheet1.xml
        • x:工作表
          • x:sheetData:

<x:sheetData xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  <x:row r="1" spans="1:1" x14ac:dyDescent="0.25" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
    <x:c r="A1">
      <x:v>7.5</x:v>
    </x:c>
  </x:row>
  <x:row r="2" spans="1:1" x14ac:dyDescent="0.25" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
    <x:c r="A2">
      <x:v>7.4999998999999997</x:v>
    </x:c>
  </x:row>
  <x:row r="3" spans="1:1" x14ac:dyDescent="0.25" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
    <x:c r="A3" s="1">
      <x:v>7.49</x:v>
    </x:c>
  </x:row>
</x:sheetData>

这就是文件中的内容(<x:v/>元素代表“值”)。 Excel不将“字符串存储在单元格中”,它存储值,并且还存储环境中描述如何向用户显示内容的所有内容。 7.4999999的值几乎是7.5,在Excel中显示为7.5,但存储为7.4999999。 7.5没有存储,除非您尝试重新创建所有Excel的显示规则,否则无法重新创建它。