Есть ли простой способ конвертировать файл.xls в файл.csv? (Excel)
Есть ли простой способ конвертировать файл.xls в файл.csv? (Excel)
в коде C#?
я имею в виду взять существующий файл.xls и преобразовать их в файл.csv
заранее спасибо
9 ответов
Вот метод C#, чтобы сделать это. Не забудьте добавить свою собственную обработку ошибок - это в основном предполагает, что все работает ради краткости. Это 4.0+ только фреймворк, но это в основном из-за worksheetNumber
параметр. Вы можете перегружать метод, если вам нужно поддерживать более ранние версии.
static void ConvertExcelToCsv(string excelFilePath, string csvOutputFile, int worksheetNumber = 1) {
if (!File.Exists(excelFilePath)) throw new FileNotFoundException(excelFilePath);
if (File.Exists(csvOutputFile)) throw new ArgumentException("File exists: " + csvOutputFile);
// connection string
var cnnStr = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=\"Excel 8.0;IMEX=1;HDR=NO\"", excelFilePath);
var cnn = new OleDbConnection(cnnStr);
// get schema, then data
var dt = new DataTable();
try {
cnn.Open();
var schemaTable = cnn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (schemaTable.Rows.Count < worksheetNumber) throw new ArgumentException("The worksheet number provided cannot be found in the spreadsheet");
string worksheet = schemaTable.Rows[worksheetNumber - 1]["table_name"].ToString().Replace("'", "");
string sql = String.Format("select * from [{0}]", worksheet);
var da = new OleDbDataAdapter(sql, cnn);
da.Fill(dt);
}
catch (Exception e) {
// ???
throw e;
}
finally {
// free resources
cnn.Close();
}
// write out CSV data
using (var wtr = new StreamWriter(csvOutputFile)) {
foreach (DataRow row in dt.Rows) {
bool firstLine = true;
foreach (DataColumn col in dt.Columns) {
if (!firstLine) { wtr.Write(","); } else { firstLine = false; }
var data = row[col.ColumnName].ToString().Replace("\"", "\"\"");
wtr.Write(String.Format("\"{0}\"", data));
}
wtr.WriteLine();
}
}
}
Оформить заказ .SaveAs()
метод в объекте Excel.
wbWorkbook.SaveAs("c:\yourdesiredFilename.csv", Microsoft.Office.Interop.Excel.XlFileFormat.xlCSV)
Или следующее:
public static void SaveAs()
{
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.ApplicationClass();
Microsoft.Office.Interop.Excel.Workbook wbWorkbook = app.Workbooks.Add(Type.Missing);
Microsoft.Office.Interop.Excel.Sheets wsSheet = wbWorkbook.Worksheets;
Microsoft.Office.Interop.Excel.Worksheet CurSheet = (Microsoft.Office.Interop.Excel.Worksheet)wsSheet[1];
Microsoft.Office.Interop.Excel.Range thisCell = (Microsoft.Office.Interop.Excel.Range)CurSheet.Cells[1, 1];
thisCell.Value2 = "This is a test.";
wbWorkbook.SaveAs(@"c:\one.xls", Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlShared, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
wbWorkbook.SaveAs(@"c:\two.csv", Microsoft.Office.Interop.Excel.XlFileFormat.xlCSVWindows, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlShared, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
wbWorkbook.Close(false, "", true);
}
Установите эти 2 пакета
<packages>
<package id="ExcelDataReader" version="3.3.0" targetFramework="net451" />
<package id="ExcelDataReader.DataSet" version="3.3.0" targetFramework="net451" />
</packages>
Вспомогательная функция
using ExcelDataReader;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ExcelToCsv
{
public class ExcelFileHelper
{
public static bool SaveAsCsv(string excelFilePath, string destinationCsvFilePath)
{
using (var stream = new FileStream(excelFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
IExcelDataReader reader = null;
if (excelFilePath.EndsWith(".xls"))
{
reader = ExcelReaderFactory.CreateBinaryReader(stream);
}
else if (excelFilePath.EndsWith(".xlsx"))
{
reader = ExcelReaderFactory.CreateOpenXmlReader(stream);
}
if (reader == null)
return false;
var ds = reader.AsDataSet(new ExcelDataSetConfiguration()
{
ConfigureDataTable = (tableReader) => new ExcelDataTableConfiguration()
{
UseHeaderRow = false
}
});
var csvContent = string.Empty;
int row_no = 0;
while (row_no < ds.Tables[0].Rows.Count)
{
var arr = new List<string>();
for (int i = 0; i < ds.Tables[0].Columns.Count; i++)
{
arr.Add(ds.Tables[0].Rows[row_no][i].ToString());
}
row_no++;
csvContent += string.Join(",", arr) + "\n";
}
StreamWriter csv = new StreamWriter(destinationCsvFilePath, false);
csv.Write(csvContent);
csv.Close();
return true;
}
}
}
}
Использование:
var excelFilePath = Console.ReadLine();
string output = Path.ChangeExtension(excelFilePath, ".csv");
ExcelFileHelper.SaveAsCsv(excelFilePath, output);
Мне пришлось придумать гибридное решение после обновления до Visual Studio 2022 и тестирования наиболее подходящих ответов, чтобы это сработало.
Во-первых, нам нужно установить следующие пакеты Nuget: ExcelDataReader , ExcelDataReader.DataSet и System.Text.Encoding.CodePages .
Затем, ради чистой архитектуры, создайте отдельный класс в соответствующем пространстве имен:
using ExcelDataReader;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace YourProjectNameSpace
{
public class ExcelFileHelper
{
/// <summary>
/// Converts a given XLS into CSV file format.
/// </summary>
public static bool SaveAsCsv(string excelFilePath, string destinationCsvFilePath)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
using (var stream = new FileStream(excelFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
IExcelDataReader reader = null;
if (excelFilePath.EndsWith(".xls"))
{
reader = ExcelReaderFactory.CreateBinaryReader(stream);
}
else if (excelFilePath.EndsWith(".xlsx"))
{
reader = ExcelReaderFactory.CreateOpenXmlReader(stream);
}
if (reader == null)
return false;
var ds = reader.AsDataSet(new ExcelDataSetConfiguration()
{
ConfigureDataTable = (tableReader) => new ExcelDataTableConfiguration()
{
UseHeaderRow = false
}
});
var csvContent = string.Empty;
int row_no = 0;
while (row_no < ds.Tables[0].Rows.Count)
{
var arr = new List<string>();
for (int i = 0; i < ds.Tables[0].Columns.Count; i++)
{
arr.Add(ds.Tables[0].Rows[row_no][i].ToString());
}
row_no++;
csvContent += string.Join(",", arr) + "\n";
}
StreamWriter csv = new StreamWriter(destinationCsvFilePath, false);
csv.Write(csvContent);
csv.Close();
return true;
}
}
}
}
Обратите внимание, что мне пришлось включить эту строку в начало функции:
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Если строка сверху опущена, вы можете получить следующую ошибку:
NotSupportedException: нет данных для кодирования 1252
Поэтому обязательно используйте его для лучшей совместимости.
Наконец, используйте пример:
var execPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)?.Replace("file:\\", "");
string FileNameXLS = "\\file.xls";
string FileNameCSV = "\\file.csv";
Console.WriteLine("Exporting file to CSV...." + "\n");
ExcelFileHelper.SaveAsCsv(execPath + FileNameXLS, execPath + FileNameCSV);
Console.WriteLine("File exported to CSV!" + "\n");
Мне нужно сделать то же самое. Я закончил с чем-то похожим на Kman
static void ExcelToCSVCoversion(string sourceFile, string targetFile)
{
Application rawData = new Application();
try
{
Workbook workbook = rawData.Workbooks.Open(sourceFile);
Worksheet ws = (Worksheet) workbook.Sheets[1];
ws.SaveAs(targetFile, XlFileFormat.xlCSV);
Marshal.ReleaseComObject(ws);
}
finally
{
rawData.DisplayAlerts = false;
rawData.Quit();
Marshal.ReleaseComObject(rawData);
}
Console.WriteLine();
Console.WriteLine($"The excel file {sourceFile} has been converted into {targetFile} (CSV format).");
Console.WriteLine();
}
Если есть несколько листов, это будет потеряно при конвертации, но вы можете зациклить количество листов и сохранить каждый как csv.
Это модификация ответа nate_weldon с некоторыми улучшениями:
- Более надежное освобождение объектов Excel
- Задавать
application.DisplayAlerts = false;
перед попыткой сохранить, чтобы скрыть подсказки
Также обратите внимание, что application.Workbooks.Open
а также ws.SaveAs
методы ожидают sourceFilePath
а также targetFilePath
быть полными путями (т.е. путь к каталогу + имя файла)
private static void SaveAs(string sourceFilePath, string targetFilePath)
{
Application application = null;
Workbook wb = null;
Worksheet ws = null;
try
{
application = new Application();
application.DisplayAlerts = false;
wb = application.Workbooks.Open(sourceFilePath);
ws = (Worksheet)wb.Sheets[1];
ws.SaveAs(targetFilePath, XlFileFormat.xlCSV);
}
catch (Exception e)
{
// Handle exception
}
finally
{
if (application != null) application.Quit();
if (ws != null) Marshal.ReleaseComObject(ws);
if (wb != null) Marshal.ReleaseComObject(wb);
if (application != null) Marshal.ReleaseComObject(application);
}
}
Я интегрирую @mattmc3 aswer. Если вы хотите преобразовать файл xlsx, вы должны использовать эту строку подключения (строка, предоставленная matt, работает для форматов xls, а не xlsx):
var cnnStr = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;IMEX=1;HDR=NO\"", excelFilePath);
У меня была аналогичная проблема ... Преобразование входящих транзакций, таких как xlsx, в разделенные табуляцией для автоматической обработки существующей системой. Должен работать без присмотра. После просмотра множества решений на нескольких разных сайтах и опробования двух из них, используя MS Office Excel для C#, как указано выше, и столкнувшись с проблемами с разными версиями MS Office и более старыми версиями, возможно, на ПК, и не имея возможности контролировать это . В итоге я пошел с ...
Aspose.Cells через NuGet. Решением были четыре строчки кода.
string soureFilePath = "my/source/path/file.xlsx";
string targetFilePath = "my/output/path/file.txt";
var book = new Workbook(soureFilePath);
book.Save(targetFilePath, SaveFormat.Tsv);
Он преобразовал только лист 1 и проигнорировал листы 2 и 3, но для меня это нормально. Я предполагаю, что у него есть функция для преобразования всех из них, если это необходимо, мне просто это не нужно, поэтому я не смотрел на это.
Их веб-сайт, если люди хотят просмотреть свою информацию или лицензионное соглашение (бесплатное использование).
Легко управлять электронными таблицами | Универсальная библиотека Aspose.Cells https://products.aspose.com/cells
Примечание. Я не работаю в Aspose, я не связан с Aspose и не получаю никакой прибыли от этой публикации.
Я поддерживаю несколько библиотек, которые максимально упрощают преобразование Excel в CSV: Sylvan.Data.Excel и Sylvan.Data.Csv . Sylvan.Data.Excel можно использовать для чтения,.xlsb
, и.xls
файлы. Однако он может писать только.xlsx
файлы.
Вот минимальный пример преобразования электронной таблицы Excel в CSV:
using Sylvan.Data.Csv;
using Sylvan.Data.Excel;
using var reader = ExcelDataReader.Create("MyData.xlsx");
using var csvWriter = CsvDataWriter.Create("MyData.csv");
csvWriter.Write(reader);
Эти библиотеки не имеют внешних зависимостей, кроме библиотек времени выполнения .NET; они не требуют установки Excel. Они ориентированы на последние поддерживаемые версии .NET и могут работать на разных платформах. Они также являются самыми быстрыми библиотеками в экосистеме .NET . Они лицензированы MIT, поэтому их можно свободно использовать.