Нужно скопировать из CSV в книгу Excel. Причем количество строк может быть весьма большим и там есть строки на русском языке. Пока удается нормально работать только одному варианту:
DataTable csvData = new DataTable();
using (TextFieldParser csvReader = new TextFieldParser(this.out_file, Encoding.GetEncoding(1251)))
{
csvReader.SetDelimiters(new string[] { ";" });
csvReader.HasFieldsEnclosedInQuotes = true;
//read column namesstring[] colFields = csvReader.ReadFields();
foreach (string column in colFields)
{
DataColumn datecolumn = new DataColumn(column);
datecolumn.AllowDBNull = true;
csvData.Columns.Add();
}
int strnum = 2;
while (!csvReader.EndOfData)
{
if (this.backgroundWorker1.CancellationPending)
return;
string[] fieldData = csvReader.ReadFields();
//Making empty value as nullfor (int i = 0; i < fieldData.Length; i++)
{
if (this.backgroundWorker1.CancellationPending)
return;
WS_mergexls.Cells[i + 1][strnum] = fieldData[i];
}
strnum++;
}
}
Но уж больно долго этот код выполняется.
Пробую просто открыть книгу
App.Workbooks.OpenText(out_file,
Excel.XlPlatform.xlWindows,
1,
Excel.XlTextParsingType.xlDelimited,
Excel.XlTextQualifier.xlTextQualifierDoubleQuote,
true, //Разделители одинарныеfalse, //Разделители :Tabtrue, //Semicolonfalse, //Commafalse, //Spacefalse, //Other
Type.Missing, //OtherChar
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing);
Microsoft.Office.Interop.Excel.Worksheet objExcelWorksheet = App.Workbooks[1].Sheets[1];
if (objExcelWorksheet != null)
{
int columnCount = objExcelWorksheet.UsedRange.Columns.Count;
for (int i = 1; i < columnCount + 1; i++)
{
if (objExcelWorksheet.Cells[1, i].Value != null)
{
if (!lstColumnsNames.Contains(objExcelWorksheet.Cells[1, i].Value.ToString()))
lstColumnsNames.Add(objExcelWorksheet.Cells[1, i].Value.ToString());
}
}
}
Здравствуйте, bmooh, Вы писали:
B>Нужно скопировать из CSV в книгу Excel. Причем количество строк может быть весьма большим и там есть строки на русском языке. Пока удается нормально работать только одному варианту:
Несколько уточняющих вопросов:
Это standalone приложение или плагин к офису?
Если это отдельное приложение, то какие требования к поддерживаемым формататм: .xls/.xlsx (собственно, вопрос даже — можно ли обойтись работой с .xlsx)?
Этот документ — это какой-то ваш шаблон (т.е. вы можете его доработать под себя) или вы не имеете доступа к шаблону и никак предварительно его подготовить нельзя?
Структура csv файла известна заранее (столбцы, количество, тип, ...) или это произвольный csv?
Какую версию офиса надо поддерживать?
Ну и ещё уточню — а вы пробовали эти csv загрузить средствами самого Excel (т.е. не программно). В 2013/2016 Excel это закладка "Data", кнопка "From Text"? Получилось ли загрузить так и устраивает ли скорость такой загрузки?
Здравствуйте, Михаил Романов, Вы писали:
МР>Ну и ещё уточню — а вы пробовали эти csv загрузить средствами самого Excel (т.е. не программно). В 2013/2016 Excel это закладка "Data", кнопка "From Text"? Получилось ли загрузить так и устраивает ли скорость такой загрузки?
Нет. Я пишу отдельное приложение в котором нужно из готового csv (генерится определенным perl-скриптом) получить в ячейки чтобы потом скопировать в другую книгу. Стркутура csv фиксированна известна заранее.
Вот если Worksheet.Querytables использовать как там задать что файл в win-1251 ? Пока видится мне единственным вменяемым способом.
Здравствуйте, bmooh, Вы писали:
B>Вот если Worksheet.Querytables использовать как там задать что файл в win-1251 ? Пока видится мне единственным вменяемым способом.
Если я правильно понимаю, то через свойство TextFilePlatform
Т.е. строчку в вашем последнем примере
А вообще рекомендую вместо выискивания нюансов по документации просто запустить в Excel запись макросов, настроить импорт, запустить, а потом посмотреть, что записалось в макросе.
Здравствуйте, bmooh, Вы писали:
B>Нет. Я пишу отдельное приложение в котором нужно из готового csv (генерится определенным perl-скриптом) получить в ячейки чтобы потом скопировать в другую книгу. Стркутура csv фиксированна известна заранее.
Ну тогда смотрите и выбирайте:
Не использовать API Excel и работать непосредственно с форматом. Вы так и не сказали, нужно ли поддерживать совместимость с .xls, но если нет, то можно взять, например, ClosedXML. На странице с документацией у них просто куча примеров на все случаи жизни
Использовать встроенные средства импорта. Помимо упомянутых QueryTable есть также достаточно навороченный механизм импорта из XML: Xml Mapping. Правда в вашем случае это, скорее излишество, но если вдруг заинтересуетесь: Creating an XML Mapping Schema in Excel 2010 или я когда-то описывал этот вариант
. Я так с Excel никогда не работал, но идея кажется разумной, т.к. везде основным источником торможения при манипуляции Excel называется работа через COM и Interop
Здравствуйте, bmooh, Вы писали:
B>Нужно скопировать из CSV в книгу Excel. Причем количество строк может быть весьма большим и там есть строки на русском языке. Пока удается нормально работать только одному варианту:
Здравствуйте, Михаил Романов, Вы писали:
МР>Здравствуйте, bmooh, Вы писали:
B>>Вот если Worksheet.Querytables использовать как там задать что файл в win-1251 ? Пока видится мне единственным вменяемым способом. МР>Если я правильно понимаю, то через свойство TextFilePlatform МР>Т.е. строчку в вашем последнем примере МР>
МР>А вообще рекомендую вместо выискивания нюансов по документации просто запустить в Excel запись макросов, настроить импорт, запустить, а потом посмотреть, что записалось в макросе.
Здравствуйте, bmooh, Вы писали:
B>Нужно скопировать из CSV в книгу Excel. Причем количество строк может быть весьма большим и там есть строки на русском языке. Пока удается нормально работать только одному варианту:
Можете попробовать CSV 4180. Это расширение для Excel, которое позволяет открывать cvs согласно RFC 4180.
Далее можно сделать так:
using System;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Excel;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Application excel = new Application();
excel.DisplayAlerts = false;
try
{
Object[,] fileConverters = (Object[,])excel.FileConverters[Type.Missing, Type.Missing];
int converterIndex = 0;
for (converterIndex = 1; converterIndex <= fileConverters.GetLength(0); converterIndex++)
{
String convertName = (String)fileConverters[converterIndex, 1];
if(convertName.StartsWith("CSV [RFC 4180]"))
break;
}
if (converterIndex == 0)
throw new ApplicationException("The convert was not found.");
Workbook workbook = excel.Workbooks.Open(Filename: @"01_total.csv", Converter: converterIndex);
Worksheet objExcelWorksheet = (Worksheet)excel.Workbooks[1].Sheets[1];
if (objExcelWorksheet != null)
{
int rowCount = objExcelWorksheet.UsedRange.Rows.Count;
int columnCount = objExcelWorksheet.UsedRange.Columns.Count;
for (Int32 rowIndex = 1; rowIndex < rowCount + 1; rowIndex++)
for (int columnIndex = 1; columnIndex < columnCount + 1; columnIndex++)
{
Range range = (Range)objExcelWorksheet.Cells[rowIndex, columnIndex];
if (range.Value != null)
{
Console.WriteLine(range.Value);
}
}
}
}
finally
{
try
{
excel.Application.Quit();
}
catch
{
}
try
{
excel.Quit();
}
catch
{
}
Marshal.FinalReleaseComObject(excel);
}
}
}
}
----
"Ответить на вопрос — значит согласиться с правильностью его постановки.", Карстен Бредемайер
Здравствуйте, Михаил Романов, Вы писали:
B>>Нет. Я пишу отдельное приложение в котором нужно из готового csv (генерится определенным perl-скриптом) получить в ячейки чтобы потом скопировать в другую книгу. Стркутура csv фиксированна известна заранее.
МР>Ну тогда смотрите и выбирайте: