24

I want my application to go and find a excel file and convert it into a .xlsx file instead.

Here's what I'm currently doing;

var fileName = @"Z:\0328\orders\PurchaseOrder.csv";
FileInfo f = new FileInfo(fileName);
f.MoveTo(Path.ChangeExtension(fileName, ".xlsx"));
var Newfile = @"Z:\0328\orders\PurchaseOrder.xlsx";

Now this does work. It changes the file extension to my desired format. However, the file then become 'corrupt' or at least Excel refuses to open it and neither will my application when I try to venture further.

Does anyone have a solution/work-around?

Abhishek
  • 2,925
  • 4
  • 34
  • 59
William
  • 6,332
  • 8
  • 38
  • 57
  • 1
    you cannot do it by directly changing the file extension. Try to use any third party dll. – Saravanan May 24 '13 at 10:01
  • Could I open the file and save it as a new format? Possible? – William May 24 '13 at 10:03
  • Yes, open it and save to the new format will work. Should be possible to get an Excel VBA macro to do it, if that helps – Stochastically May 24 '13 at 10:04
  • You need to use something like the [Open XML SDK](http://msdn.microsoft.com/en-us/library/office/bb448854.aspx) from Microsoft to do that. However, unless you plan to add some additional features (embed formulas, fonts, colors, diagrams, etc.) you can simply stick with the CSV file, as Excel will open that happily. – Christian.K May 24 '13 at 10:06
  • You could use EPPlus or NPOI which allow you to write native XLSX files. – connectedsoftware May 24 '13 at 10:07

7 Answers7

18

For those who want to use Interop instead of an external library, you can simply do this:

Application app = new Application();
Workbook wb = app.Workbooks.Open(@"C:\testcsv.csv", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
wb.SaveAs(@"C:\testcsv.xlsx", XlFileFormat.xlOpenXMLWorkbook, Type.Missing, Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
wb.Close();
app.Quit();

The second argument of Workbook.SaveAs determines the true format of the file. You should make the filename extension match that format so Excel doesn't complain about corruption. You can see a list of the types and what they mean on MSDN.

http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.xlfileformat.aspx

As always, please keep Microsoft's considerations in mind if this functionality is intended for a server environment. Interop may not be the way to go in that situation:

http://support.microsoft.com/kb/257757

Rakuen42
  • 1,407
  • 15
  • 16
  • 3
    Just tested it - works perfectly well with Office 2013, thanks! Also wanted to add that in .net 4 you can skip all those nasty Type.Missing. You can simply call: Workbook wb = app.Workbooks.Open(csvPath); wb.SaveAs(xlsxPath, XlFileFormat.xlOpenXMLWorkbook, AccessMode: XlSaveAsAccessMode.xlExclusive); – kDar Feb 09 '14 at 19:09
  • @kDar - your code saves the file in Password protected mode. – SKG Jul 29 '14 at 22:27
  • How do I overwrite the file without showing a prompt to the user if a file already exist with that name? – Si8 Dec 22 '16 at 15:06
  • @Si8 `app.DisplayAlerts = false;` before the save. REMEMBER to set it to true after! (app is the name of the Application, `Application app = new Application();`) – DDuffy Mar 07 '17 at 12:55
  • Thank you for the response @DDuffy... I was able to figure it out after looking through the API. Thanks for the help. – Si8 Mar 08 '17 at 19:53
  • Drawbacks are: requires MS Office and slowest converter. – Gray Programmerz Jun 30 '22 at 09:05
13

I would parse in the CSV file and use this to write out an Excel file : https://github.com/JanKallman/EPPlus

Magnetron
  • 7,495
  • 1
  • 25
  • 41
Mark Redman
  • 24,079
  • 20
  • 92
  • 147
7

This code should open the file you want and save it to the format without corrupting it.

  1. Renames the file
  2. Creates the Excel.Application instance
  3. Opens the file
  4. Does a save as to the desired format
  5. Closes it

    using Excel = Microsoft.Office.Interop.Excel;
    
    private void Convert_CSV_To_Excel()
    {
    
        // Rename .csv To .xls
        System.IO.File.Move(@"d:\Test.csv", @"d:\Test.csv.xls");
    
        var _app = new Excel.Application();
        var _workbooks = _app.Workbooks;
    
        _workbooks.OpenText("Test.csv.xls",
                                 DataType: Excel.XlTextParsingType.xlDelimited,
                                 TextQualifier: Excel.XlTextQualifier.xlTextQualifierNone,
                                 ConsecutiveDelimiter: true,
                                 Semicolon: true);
    
        // Convert To Excle 97 / 2003
        _workbooks[1].SaveAs("NewTest.xls", Excel.XlFileFormat.xlExcel5);
    
        _workbooks.Close();
    }
    
Ben Black
  • 3,751
  • 2
  • 25
  • 43
arash
  • 81
  • 1
  • 1
  • 4
    Can you explain your answer please? code-only answers are generally not acceptable because they don't necessarily help the asker to learn from their mistakes, etc. – Wai Ha Lee May 13 '15 at 10:32
  • +1 for xlExcel5 - because it does not give message that inner data is in other format when you open excel file. – Romil Kumar Jain Jun 28 '16 at 19:08
  • It works also with `_workbooks[1].SaveAs("testcsv.xlsx", Excel.XlFileFormat.xlWorkbookDefault);` But rename the csv file to xls is necessary. – Saftpresse99 Jun 13 '18 at 08:33
3

I would recommend using the following technique:

  1. http://kbcsv.codeplex.com/ this reads CSV files in very easily and is very robust.
  2. Create a datatable from the csv via the kbcsv extensions.
  3. Use the eppplus library and its LoadFromDataTable to create a valid xlsx file (https://github.com/JanKallman/EPPlus)
  4. done!

Advantages:

  • It is faster than excel interop
  • KBCSV is more robust than excels csv reading methods.
  • It is availabe in environments witohout office.
Magnetron
  • 7,495
  • 1
  • 25
  • 41
Christian Sauer
  • 10,351
  • 10
  • 53
  • 85
  • EPPLus can Load CSV directly via LoadFromText method :-) var range = sheet.Cells["A1"].LoadFromText(new FileInfo(CSV_FilePath), format, TableStyles.Medium27, true); Here is full example http://tinyurl.com/odyz25n – Muflix Feb 28 '15 at 19:35
1

Try this class; takes in any CSV or TXT file with any delimiter including a tab and converts to Excel (.xls)

examples:

  • convertToExcel(@"path to file", "\t", ".csv");
  • convertToExcel(@"path to file", "\|", ".txt");

    public static void convertToExcel(string fileName, string splitter, string extension)
    {
        string newFileName = fileName.Replace("." + extension, ".xls");
    
        string[] lines = File.ReadAllLines(fileName, Encoding.UTF8);
    
        int columnCounter = 0;
    
        foreach (string s in lines)
        {
            string[] ss = s.Trim().Split(Convert.ToChar(splitter));
    
            if (ss.Length > columnCounter)
                columnCounter = ss.Length;
        }           
    
        HSSFWorkbook workbook = new HSSFWorkbook();
        var sheet = workbook.CreateSheet("Data");
        var rowIndex = 0;
        var rowExcel = sheet.CreateRow(rowIndex);
    
        foreach (string s in lines)
        {
            rowExcel = sheet.CreateRow(rowIndex);
    
            string[] ss = s.Trim().Split(Convert.ToChar(splitter));
    
            for (int i = 0; i < columnCounter; i++)
            {
                string data = !String.IsNullOrEmpty("s") && i < ss.Length ? ss[i] : "";
                rowExcel.CreateCell(i).SetCellType(CellType.String);
                rowExcel.CreateCell(i).SetCellValue(data);                    
            }
    
            rowIndex++;
        }
    
        for (var i = 0; i < sheet.GetRow(0).LastCellNum; i++)
            sheet.AutoSizeColumn(i);
    
        using (FileStream file = new FileStream(newFileName, FileMode.Create, FileAccess.Write))
        {
            workbook.Write(file);
            file.Close();
        }
    }
    
0

I would recommend Closed XML which is a wrapper around Open XML SDK. Check out their examples. It's pretty easy to create a .xlsx file.

cvraman
  • 1,687
  • 1
  • 12
  • 18
0
public static void ConvertFromCsvWithNpoi(string fileName, char splitter)
{
    var newFileName = Path.ChangeExtension(fileName, ".xlsx");
    string[] lines = File.ReadAllLines(fileName, Encoding.UTF8);

    IWorkbook workbook = new XSSFWorkbook();
    var sheet = workbook.CreateSheet(Path.GetFileName(newFileName));
    var rowIndex = 0;

    foreach (string line in lines)
    {
        var row = sheet.CreateRow(rowIndex);

        string[] lineStr = line.Trim().Split(splitter);

        for (int i = 0; i < lineStr.Length; i++)
        {
            string data = String.IsNullOrEmpty(line) ? string.Empty : lineStr[i].Trim();
            double sum = 0;
            if (double.TryParse(data, out sum))
            {
                row.CreateCell(i).SetCellValue(sum);
            }
            else
            {
                row.CreateCell(i).SetCellValue(data);
            }
        }

        rowIndex++;
    }

    for (var i = 0; i < sheet.GetRow(0).LastCellNum; i++)
        sheet.AutoSizeColumn(i);

    using (FileStream file = new FileStream(newFileName, FileMode.Create, FileAccess.Write))
    {
        workbook.Write(file);
        file.Close();
    }
}
zzhelev
  • 1
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 18 '22 at 03:00