Я использую OpenXmlReader в программе на C# для чтения файлов Excel. Для моих целей (сравнения значений) мне нужны точные значения ячеек без каких-либо изменений.
Однако OpenXmlReader интерпретирует определенные типы значений ячеек Excel (конкретно, проценты, даты и время) раздражающим образом, который я, похоже, не могу контролировать.
Представьте, что это строка Excel (то, что я ожидаю прочитать):
BNK | BNK_DC | GROUP | GROUP | 8 | 0,12% | 0,14% | 0,15% | 0,17% | 0,18%
Вот как выглядит строка на моей консоли отладки:
BNK | BNK_DC | GROUP | GROUP | 8 | 1.1561E-3 | 1.3554245994127801E-3 | 1.5389154190192354E-3 | 1.7010741265663695E-3 |1.8389123386463213E-3
В принципе, строки читаются правильно, и простое целое число тоже. Однако проценты превращаются во что-то, что я не могу понять или с чем работать.
Нечто подобное происходит, когда я пытаюсь прочитать дату или время.
Строка файла excel:
04.04.2018 | Adam Smith | 09:30 | 17:30 | 8,0 | Apr | Q2
Что возвращает OpenXmlReader:
43194 | Adam Smith | 0.39583333333333331 | 0.72916666666666663 | 8 | Apr | Q2
Как видите, дата и время превратились в нечто, чего я не понимаю.
Я предполагаю, что это может быть связано с определенным образом, как проценты, время и даты хранятся внутри Excel. Если да, как мне преобразовать эти значения обратно в читаемый формат?
Это точный код, который я использую для чтения файлов Excel с помощью класса OpenXmlReader и отображения их в моей консоли отладки:
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Diagnostics;
public void ExcelReader(SpreadsheetDocument document)
{
var wbp = document.WorkbookPart;
var wsp = wbp.WorksheetParts.First();
OpenXmlReader reader = OpenXmlReader.Create(wsp);
string text;
while (reader.Read())
{
if (reader.ElementType == typeof(Row))
{
reader.ReadFirstChild();
do
{
if (reader.ElementType == typeof(Cell))
{
Cell c = (Cell)reader.LoadCurrentElement();
string cellValue;
if (c.DataType != null && c.DataType == CellValues.SharedString)
{
SharedStringItem ssi = wbp.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(int.Parse(c.CellValue.InnerText));
cellValue = ssi.Text.Text;
}
else
{
cellValue = c.CellValue?.InnerText;
}
Debug.Write($"{cellValue} | ");
}
} while (reader.ReadNextSibling());
Debug.Write("\n");
}
}
document.Close();
}
Я взял этот код в основном из первого ответа в следующем потоке: Использование OpenXmlReader
Итак, как мне получить мои фактические проценты, даты и время из Excel вместо этих странных значений? Заранее спасибо.
Дата
Дата хранится в днях после 01.01.1900.
Время
Время сохраняется в формате 24 часа * число, поэтому 24 часа * 0,395833 = 9,5 => 09:30.
Процент
Если вы используете Convert.ToSingle(number)
, 1.1561E-3
станет 0.0011561
, что составляет 0,115%.
В вашем do {} я бы посоветовал добавить переключатель (theCell.DataType.Value) {// Теперь у вас есть тип, выполните синтаксический анализ этого типа (float.Parse и т. д.)}