Home > Mobile >  .NET - How to combine multiple CSV files into one MS Excel file with multiple tabs
.NET - How to combine multiple CSV files into one MS Excel file with multiple tabs

Time:02-17

I have a .NET app that makes multiple CSV file like

1.csv
2.csv
3.csv
.
.
.

I am trying to turn them into a single .xlsx file with data of each CSV in a separate tab. I've come across a few NuGet packages that let me do that, but they all seem to have quite expensive licenses. Then I found Microsoft.Office.Interop.Excel which, for the life of me, I cannot figure out. Is there an easy way to combine multiple CSV files into one MS Excel file with multiple tabs?

CodePudding user response:

If you don't find any free package to do so, I've found EPPlus quite straightforward to use. They have a NonCommercial license if you want to try it. For commercial apps it has a price.

To make the tabs, doing ExcelPackage.Workbook.Worksheets.Add("Tab Name"); you can create a tab and then doing tab.Cells[row, colum].Value = "X" you can enter the info you need.

CodePudding user response:

You don't need any library to do that. CSV files are just text files with a certain format. All you need to do is to create a file and copy the other files into it :

Sorry for misreading the question. Here is a sample with the NPOI library usage:

var files = Directory.GetFiles(DownloadPath);
var combinedFile = Path.Combine(DownloadPath, "Combined.xlsx");
using var target = new FileStream(combinedFile, FileMode.Create, FileAccess.Write);
IWorkbook workbook = new XSSFWorkbook();
var seperator = ";";

foreach (var file in files)
{
    ISheet sheet = workbook.CreateSheet(file);
    using var sourceFile = new FileStream(file, FileMode.Open, FileAccess.Read);
    using TextReader reader = new StreamReader(sourceFile);
    var line = await reader.ReadLineAsync();
    var i = 0;
    while (!string.IsNullOrEmpty(line))
    {
        var row = sheet.CreateRow(i  );
        var values = line.Split(seperator);
        for (int j = 0; j < values.Length; j  )
        {
            var cell = row.CreateCell(j);
            cell.SetCellValue(values[j]);
        }
    } 
}

workbook.Write(target);

Please also notice that it's just a sample. You should check the documents for detailed info.

CodePudding user response:

There are multiple ways to do this. One way is to use Epplus package. Another one is to use Interop.Excel which is quite straightforward. With Interop.Excel you have more opportunities (such as you could do anything you can do manually using Excel create add in etc). Anyway, using Interop.Excel, you could use CopyFromRecordset() or even better if your files persistent is QueryTables.Add(). Here is a sample using CopyFromRecordset:

using ADODB;
using Excel=Microsoft.Office.Interop.Excel;

void Main()
{
    Excel.Application xl = new Excel.Application();
    var wb = (Excel.Workbook)xl.Workbooks.Add();
    //xl.Visible = true;

    ConnectionClass cn = new ConnectionClass();
    string path = @"c:\temp\myCSVFiles";
    string[] filenames = { "1.csv", "2.csv", "3.csv", "4.csv" };
    string connectionString = $@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={path};Extended Properties=""text;HDR=Yes;FMT=Delimited"";";
    cn.Open(connectionString, "", "", 0);
    
    for (int i = 0; i < filenames.Length; i  )
    {
        if (i > 0 && wb.Worksheets.Count < i   1) {
            wb.Worksheets.Add(After: wb.Worksheets[i]);
        }
        var ws = (Excel.Worksheet)wb.Worksheets[i 1];

        RecordsetClass rs = new RecordsetClass();
        string filename = filenames[i];
        rs.Open($@"select * from {filename}",
            cn,
            CursorTypeEnum.adOpenUnspecified,
            LockTypeEnum.adLockUnspecified, 0);

        ws.Activate();
        Excel.Range rng = ws.Range["A1"];
        for (int j = 0; j < rs.Fields.Count; j  )
        {
            rng.Offset[0, j].Value2 = rs.Fields[j].Name;
            rng.Offset[0, j].Font.Bold = true;
        }

        rng.Offset[1, 0].CopyFromRecordset(rs);
        ws.UsedRange.Columns.AutoFit();
        rs.Close();
    }
    cn.Close();
    wb.SaveAs(@"c:\temp\MyCSVStore.xlsx");
    wb.Close(SaveChanges:true);
    
    
    xl.Quit();
}
  • Related