Быстрый способ получить диапазон Excel в виде массива текстов или форматов ячеек в C#?
операции массива намного быстрее, чем операции диапазона в VSTO, поэтому в настоящее время я использую
object[,] RangeValues = wsh.get_Range("A1:" + lastCell.Address).Value2;
С хорошим эффектом. К сожалению, у меня есть противоречивые данные. Иногда есть 0.45
, а иногда 0.45%
, и, конечно, позже я вижу это как 0.0045
в коде. К сожалению, с точки зрения" бизнеса " оба значения означают 0.45
. Я не могу заставить согласованность, файлы поступают из разных источников, на которые у меня нет полномочий. Мне нужно с этим разобраться. с.
путь, конечно, будет смотреть на формат, или на отображаемый текст, и посмотреть, есть ли %
войти в него. Если есть, мне просто нужно умножить значение на 100. К сожалению, если я попытаюсь:
object[,] RangeValues = wsh.get_Range("A1:" + lastCell.Address).Text;
Я получаю сообщение, что не может преобразовать DBNull
to object[,]
. Итак, есть ли способ, который позволил бы мне загружать тексты или форматы сразу, не проходя тщательную границу листа кода на каждом шаге цикла mu?
3 ответов
Обнаружение Форматов Ячеек Excel
чтобы найти формат ячеек, используйте Excel Cell("format",A1)
функция, а не опрос типов данных, которые были бы намного медленнее, сложнее и склонны к проблемам, например: 0.45% != 45%.
private void button1_Click(object sender, EventArgs e)
{
// evaluate the Format of Cells A1 thru to A7
using (var rnEvaluate = xlApp.Range["C1:C1"].WithComCleanup())
{
for (int i = 1; i < 8; i++)
{
rnEvaluate.Resource.Value2 = "=CELL(\"format\",A" + i.ToString() + ")";
string cellFormat = GetExcelCellFormat(rnEvaluate.Resource.Value2);
System.Diagnostics.Debug.Write(cellFormat);
}
}
}
private string GetExcelCellFormat(string cellFormat = "G")
{
switch (cellFormat.Substring(0, 1))
{
case "F" :
return "Number";
break;
case "P" :
return "Percentage";
break;
case "C":
return "Currency";
break;
case "D":
return "Date";
break;
default :
return "General";
break;
}
}
на .WithComCleanup()
потому что я использую VSTO Contrib.
обнаружение всех форматов ячеек Excel сразу
есть ли способ, который бы позвольте мне загружать тексты или форматы сразу?
просто используйте вышеуказанный метод для обнаружения всех форматов ячеек (с помощью автозаполнения) и добавления их в objectArray. Скажем, например, я хотел знать форматы ячеек для столбцов A & B:
используя этот код VBA, я мог бы получить все форматы ячеек (сразу без итерации по ячейкам):
Range("C1").Select
ActiveCell.Value2 = "=CELL(""format"",A1)"
'Fill Down
Range("C1").Select
Selection.AutoFill Destination:=Range("C1:C6"), Type:=xlFillDefault
'Fill Across
Range("C1:C6").Select
Selection.AutoFill Destination:=Range("C1:D6"), Type:=xlFillDefault
вот приведенный выше код VBA, преобразованный в C# и хранящий форматы в массиве объектов:
var filepath = @"C:\temp\test\book2.xlsx";
var xlApp = new Microsoft.Office.Interop.Excel.Application();
//Optional but recommended if the user shouldn't see Excel.
xlApp.Visible = false;
xlApp.ScreenUpdating = false;
//AddToMru parameter is optional, but recommended in automation scenarios.
var workbook = xlApp.Workbooks.Open(filepath, AddToMru: false);
//This operation may take a little bit of time but no where near 15 minutes!!!
var cell = xlApp.Range["C1:C1"];
cell.Value2 = "=CELL(\"format\",A1)";
//Fill Down
cell.AutoFill(xlApp.Range["C1:C6"], Microsoft.Office.Interop.Excel.XlAutoFillType.xlFillDefault);
//Fill Across
cell = xlApp.Range["C1:C6"];
cell.AutoFill(xlApp.Range["C1:D6"], Microsoft.Office.Interop.Excel.XlAutoFillType.xlFillDefault);
//Get cell formats into object array
object[,] rangeFormats = xlApp.get_Range("C1:D6").Value2;
Excel Процент Преобразования Трюк
у меня есть некоторые противоречивые данные. Иногда есть 0.45, а иногда 0.45%
если у вас есть только несоответствия данных с % значения тогда вот трюк.
предположительно процентные значения будут в столбце, чтобы преобразовать их, скопируйте столбец значений (в столбце A):
убедитесь, что вы установили столбец со значениями 100 (как показано в столбце B)
щелкните правой кнопкой мыши ячейку в столбце 100 и выберите Вставить специальный:
выберите значения и умножьте:
Excel преобразует их в реальные цифры:
очевидно это можно сделать программно. Просто запишите операцию как макрос и преобразуйте VBA в C#.
и, конечно, позже я вижу это как 0.0045 в коде.
Примечание: код прав, 0.45% не 45%, 0.45% меньше половины процента! Если конкретный клиент отправляет вам файлы, ожидая, что вы нарушите законы математики и обработаете 0.45% = 45% , то есть хороший шанс, что они могут внезапно начать получать 100x больше или 100x меньше. Я бы вежливо заметил, что они должны это изменить. Не пытайтесь программировать вокруг этого. Если именно поэтому вы хотите посмотреть на форматы ячеек, то все, что вы делаете, это устранение симптома, а не исправление основной причины, которая усугубит проблему и скроет гораздо большую проблему. Просто вежливо укажите на это к источникам вы не имеете никакого контроля над могут быть некоторые массовые проблемы с помощью X100 fold и настаивать на том, что его необходимо исправить. В противном случае я ожидаю увидеть веселый рассказ о нем в DailyWTF с этот код:
var val = rangeValues[1,1].ToString();
var cellFormat = rangeFormat[1,1].ToString();
if (val.EndsWith("%") && val.Replace("%","") < 1 && cellFormat == "G") {
dailyWTFval = val.Replace("%","") * 100;
}
else
dailyWTFval = val;
}
Я думаю, что самый простой способ прочитать большое количество несогласованных данных из excel будет следующим
в C# сохраните файл excel в XML-таблице 2003 (*xml). Это создаст xml-файл со всеми данными и стилем. C# метод сохранения-Workbook.SaveAs со значением FileFormat = XlFileFormat.xlXMLSpreadsheet
разбирать xml-файл и извлекать данные в форматах
- удалить временные файл
XML
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Bottom"/>
<Borders/>
<Font ss:FontName="Calibri" x:CharSet="204" x:Family="Swiss" ss:Size="11"
ss:Color="#000000"/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
<Style ss:ID="s62">
<NumberFormat ss:Format="0%"/>
</Style>
</Styles>
<Worksheet ss:Name="Sheet1">
<Table ss:ExpandedColumnCount="1" ss:ExpandedRowCount="5" x:FullColumns="1"
x:FullRows="1" ss:DefaultRowHeight="15">
<Row ss:AutoFitHeight="0">
<Cell>
<Data ss:Type="String">Data</Data>
</Cell>
</Row>
<Row ss:AutoFitHeight="0">
<Cell>
<Data ss:Type="Number">45</Data>
</Cell>
</Row>
<Row ss:AutoFitHeight="0">
<Cell ss:StyleID="s62">
<Data ss:Type="Number">0.45</Data>
</Cell>
</Row>
<Row ss:AutoFitHeight="0">
<Cell>
<Data ss:Type="String">String</Data>
</Cell>
</Row>
<Row ss:AutoFitHeight="0">
<Cell>
<Data ss:Type="Number">45.5</Data>
</Cell>
</Row>
</Table>
</Worksheet>
Я удалил некоторые узлы для простоты. Следующие элементы должны быть проанализированы, чтобы правильно извлечь данные
- Workbook\Worksheet\Table\Row\Cell\Data-содержит данные, сформированные в инвариантную культуру
- Workbook\Worksheet\Table\Row\Cell\Data, атрибут ss: Type-содержит тип данных элемента данных содержание
- Workbook\Worksheet\Table\Row\Cell, атрибут ss:StyleID-ссылка на стиль, для вашего случая требуется только правильно идентифицировать ячейки, где число формируется в процентах (умножение до 100 требуется)
- Workbook\Styles\Style, атрибут ss: ID-id стиля, используемого для ссылки на стиль из ячеек
- Workbook\Styles\Style\NumberFormat, attrubute ss: Format-если заканчивается на % и номер типа данных - > это процент
анализатор логики:
- тип строки в ячейке - > преобразовать как есть
- тип номера в ячейке. Если формат заканчивается на " % " - > умножить на 100, в противном случае используйте как есть.
Если объемы данных не так велики(менее 200-300), можно выполнить анализ по ячейкам из C# без сохранения файла в формате xml.
Это может быть плохой способ сделать это, но подумайте о перезаписи файла excel в новый файл excel, конвертируя его в текстовый формат в процессе. Я предлагаю это только потому, что у вас может не быть прав на запись в исходном файле, в ваших комментариях к вашему вопросу. См. пример того, как вы можете преобразовать весь файл [исключая создание нового файла] здесь:https://stackoverflow.com/a/25162945/5090027
кроме того, MSDN обсуждает метод экспорта весь файл в виде текстового файла здесь, используя Spire [Disclosure-я не использовал это сам]: https://code.msdn.microsoft.com/windowsdesktop/Export-Excel-Data-to-Text-015bc013