将多个 excel 工作表读入单个制表符分隔的文本文件
Reading multiple excel sheets into a single tab delimited text file
我有多个 xls 和 xlsx 文件要转换为制表符分隔的文件。下面的代码在第一个 sheet 中读取的次数等于 sheet 的次数。例如,如果文件有三个作品sheet,第一个作品sheet 将打印到文件 3 次,而每个作品sheet 打印一次。
有什么想法吗?
Microsoft.Office.Interop.Excel.Workbook book = appTwo.Workbooks.Open(strfileName);
int numSheet = book.Worksheets.Count;
List<Microsoft.Office.Interop.Excel.Worksheet> sheets = new List<Microsoft.Office.Interop.Excel.Worksheet>();
foreach (Microsoft.Office.Interop.Excel.Worksheet sheet in book.Worksheets)
{
int numberOfSheets = 0;
System.Data.OleDb.OleDbCommand objCommand = new System.Data.OleDb.OleDbCommand("Select * From [" + dR["TABLE_NAME"].ToString() + "]", Connection1);
System.Data.OleDb.OleDbDataAdapter objAdapter = new System.Data.OleDb.OleDbDataAdapter();
objAdapter.SelectCommand = objCommand;
DataSet ds = new DataSet();
objAdapter.Fill(ds);
DataRow dataRow = ds.Tables[0].Rows[0];
if (dR["TABLE_NAME"].ToString().StartsWith("Sheet"))
{
numberOfSheets++;
}
for (int i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
for (int j = 0; j < ds.Tables[0].Columns.Count; j++)
{
if (!string.IsNullOrEmpty(ds.Tables[0].Rows[i].ItemArray[j].ToString()))
{
swOutput.Write(ds.Tables[0].Rows[i].ItemArray[j].ToString());
if (j != ds.Tables[0].Columns.Count - 1)
{
swOutput.Write('\t');
}
}```
对于你的代码,我认为问题可能出在这里 swOutput.Write(ds.Tables[0].Rows[i].ItemArray[j].ToString());
考虑到 swOutput 是在你的每个语句之外定义的,文件名没有改变,因此它将工作表写入同一个文件。
个人不希望它依赖于 Microsoft.Office.Interop.Excel
,因为这只有在 excel 机器上安装 运行 代码时才有效。
Nugets 是你的朋友,因为 excel 我用 EPPLUS and for CSV i use CsvHelper
不幸的是,Epplus 似乎不支持 .XLS 文件,但是有多种在线工具可以以编程方式将 XLS 转换为 XLSX,或者如果需要的话,您可以使用 Microsoft.Office.Interop.Excel.Workbook
仅用于转换。所以我会把这个留给你。
假设
- 所有文件都是 XLSX
- 工作表中的数据是 table 的形式,其中第一行是 headers
所以写了一些方法以及如何使用它们,
如何使用
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
var FolderWithFiles = @"D:\Temp\RubbishFolder";
foreach (FileInfo file in Directory.EnumerateFiles(FolderWithFiles,"*.xlsx",SearchOption.TopDirectoryOnly).Select(t=>new FileInfo(t)))
{
ExcelDocToCsv(file);
}
方法
private void ExcelDocToCsv(FileInfo filepath){
using (ExcelPackage doc = new ExcelPackage(filepath))
{
int NumberOfWorksheets =doc.Workbook.Worksheets.Count();
var WorkSheetNames= doc.Workbook.Worksheets.Select(w =>w.Name).ToArray();
foreach (string worksheet in WorkSheetNames)
{
var CsvFileName = Path.Combine(filepath.Directory.FullName,"[File_"+Path.GetFileNameWithoutExtension(filepath.FullName)+"] [WorkSheet_"+worksheet+"].csv");
WriteToCSV(CreateTableFromWorksheet(doc.Workbook.Worksheets[worksheet]),CsvFileName);
}
}
}
private DataTable CreateTableFromWorksheet(ExcelWorksheet worksheet)
{
DataTable dt = new DataTable();
ExcelCellAddress StartCell = worksheet.Dimension.Start;
ExcelCellAddress EndCell = worksheet.Dimension.End;
for (int i = StartCell.Column; i <= EndCell.Column; i++)
{
dt.Columns.Add(worksheet.Cells[1,i].Value.ToString());
}
for (int i = StartCell.Row+1; i <= EndCell.Row; i++)
{
DataRow row = dt.NewRow();
int r = 0;
for (int b = StartCell.Column; b <= EndCell.Column; b++)
{
row[r++] = worksheet.Cells[i, b].Value;
}
dt.Rows.Add(row);
}
return dt;
}
private void WriteToCSV(DataTable dt,string WriteTo){
// https://github.com/JoshClose/CsvHelper/issues/1399
using (var writer = new StreamWriter(WriteTo))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.Configuration.Delimiter ="\t";
foreach (DataColumn dc in dt.Columns)
{
csv.WriteField(dc.ColumnName);
}
csv.NextRecord();
foreach (DataRow dr in dt.Rows)
{
foreach (DataColumn dc in dt.Columns)
{
csv.WriteField(dr[dc]);
}
csv.NextRecord();
}
}
}
将把任何错误检查和处理留给您。
这会将文档中的每个工作表写入 csv
我有多个 xls 和 xlsx 文件要转换为制表符分隔的文件。下面的代码在第一个 sheet 中读取的次数等于 sheet 的次数。例如,如果文件有三个作品sheet,第一个作品sheet 将打印到文件 3 次,而每个作品sheet 打印一次。
有什么想法吗?
Microsoft.Office.Interop.Excel.Workbook book = appTwo.Workbooks.Open(strfileName);
int numSheet = book.Worksheets.Count;
List<Microsoft.Office.Interop.Excel.Worksheet> sheets = new List<Microsoft.Office.Interop.Excel.Worksheet>();
foreach (Microsoft.Office.Interop.Excel.Worksheet sheet in book.Worksheets)
{
int numberOfSheets = 0;
System.Data.OleDb.OleDbCommand objCommand = new System.Data.OleDb.OleDbCommand("Select * From [" + dR["TABLE_NAME"].ToString() + "]", Connection1);
System.Data.OleDb.OleDbDataAdapter objAdapter = new System.Data.OleDb.OleDbDataAdapter();
objAdapter.SelectCommand = objCommand;
DataSet ds = new DataSet();
objAdapter.Fill(ds);
DataRow dataRow = ds.Tables[0].Rows[0];
if (dR["TABLE_NAME"].ToString().StartsWith("Sheet"))
{
numberOfSheets++;
}
for (int i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
for (int j = 0; j < ds.Tables[0].Columns.Count; j++)
{
if (!string.IsNullOrEmpty(ds.Tables[0].Rows[i].ItemArray[j].ToString()))
{
swOutput.Write(ds.Tables[0].Rows[i].ItemArray[j].ToString());
if (j != ds.Tables[0].Columns.Count - 1)
{
swOutput.Write('\t');
}
}```
对于你的代码,我认为问题可能出在这里 swOutput.Write(ds.Tables[0].Rows[i].ItemArray[j].ToString());
考虑到 swOutput 是在你的每个语句之外定义的,文件名没有改变,因此它将工作表写入同一个文件。
个人不希望它依赖于 Microsoft.Office.Interop.Excel
,因为这只有在 excel 机器上安装 运行 代码时才有效。
Nugets 是你的朋友,因为 excel 我用 EPPLUS and for CSV i use CsvHelper
不幸的是,Epplus 似乎不支持 .XLS 文件,但是有多种在线工具可以以编程方式将 XLS 转换为 XLSX,或者如果需要的话,您可以使用 Microsoft.Office.Interop.Excel.Workbook
仅用于转换。所以我会把这个留给你。
假设
- 所有文件都是 XLSX
- 工作表中的数据是 table 的形式,其中第一行是 headers
所以写了一些方法以及如何使用它们,
如何使用
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
var FolderWithFiles = @"D:\Temp\RubbishFolder";
foreach (FileInfo file in Directory.EnumerateFiles(FolderWithFiles,"*.xlsx",SearchOption.TopDirectoryOnly).Select(t=>new FileInfo(t)))
{
ExcelDocToCsv(file);
}
方法
private void ExcelDocToCsv(FileInfo filepath){
using (ExcelPackage doc = new ExcelPackage(filepath))
{
int NumberOfWorksheets =doc.Workbook.Worksheets.Count();
var WorkSheetNames= doc.Workbook.Worksheets.Select(w =>w.Name).ToArray();
foreach (string worksheet in WorkSheetNames)
{
var CsvFileName = Path.Combine(filepath.Directory.FullName,"[File_"+Path.GetFileNameWithoutExtension(filepath.FullName)+"] [WorkSheet_"+worksheet+"].csv");
WriteToCSV(CreateTableFromWorksheet(doc.Workbook.Worksheets[worksheet]),CsvFileName);
}
}
}
private DataTable CreateTableFromWorksheet(ExcelWorksheet worksheet)
{
DataTable dt = new DataTable();
ExcelCellAddress StartCell = worksheet.Dimension.Start;
ExcelCellAddress EndCell = worksheet.Dimension.End;
for (int i = StartCell.Column; i <= EndCell.Column; i++)
{
dt.Columns.Add(worksheet.Cells[1,i].Value.ToString());
}
for (int i = StartCell.Row+1; i <= EndCell.Row; i++)
{
DataRow row = dt.NewRow();
int r = 0;
for (int b = StartCell.Column; b <= EndCell.Column; b++)
{
row[r++] = worksheet.Cells[i, b].Value;
}
dt.Rows.Add(row);
}
return dt;
}
private void WriteToCSV(DataTable dt,string WriteTo){
// https://github.com/JoshClose/CsvHelper/issues/1399
using (var writer = new StreamWriter(WriteTo))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.Configuration.Delimiter ="\t";
foreach (DataColumn dc in dt.Columns)
{
csv.WriteField(dc.ColumnName);
}
csv.NextRecord();
foreach (DataRow dr in dt.Rows)
{
foreach (DataColumn dc in dt.Columns)
{
csv.WriteField(dr[dc]);
}
csv.NextRecord();
}
}
}
将把任何错误检查和处理留给您。
这会将文档中的每个工作表写入 csv