1

I am trying to Merge more excel document into a single document using NPOI. Here is the code write:``

static void Main(string[] args)
    {
        DataTable dt = new DataTable();
        string[] files = new string[] { @"C:\Users\Ionut\source\repos\ExcelMergeDocument\ExcelMergeDocument\bin\Debug\TAMUExport\Project1\Report3Item.xls",
        @"C:\Users\Ionut\source\repos\ExcelMergeDocument\ExcelMergeDocument\bin\Debug\TAMUExport\Project2\Report3Item.xls"};
        for (int i = 0; i < files.Length; i++)
        {

            MergeData(files[i], dt);
        }
        ExportEasy(dt, finalImagePathReport3full);
    }

    public static string imagePathReport3full = @"\ResultReport3Item.xls";

    public static string finalImagePathReport3full = AssemblyDirectory + imagePathReport3full;


    public static string AssemblyDirectory
    {
        get
        {
            string codeBase = Assembly.GetExecutingAssembly().CodeBase;
            UriBuilder uri = new UriBuilder(codeBase);
            string path = Uri.UnescapeDataString(uri.Path);
            return System.IO.Path.GetDirectoryName(path);
        }
    }

    private static void MergeData(string path, DataTable dt)
    {
        XSSFWorkbook workbook = new XSSFWorkbook(path);
        XSSFSheet sheet = (XSSFSheet)workbook.GetSheetAt(0);
        XSSFRow headerRow = (XSSFRow)sheet.GetRow(0);
        int cellCount = headerRow.LastCellNum;
        if (dt.Rows.Count == 0)
        {
            for (int i = headerRow.FirstCellNum; i < cellCount; i++)
            {
                DataColumn column = new DataColumn(headerRow.GetCell(i).StringCellValue);
                dt.Columns.Add(column);
            }
        }
        else
        {
        }

        int rowCount = sheet.LastRowNum + 1;
        for (int i = (sheet.FirstRowNum + 1); i < rowCount; i++)
        {
            XSSFRow row = (XSSFRow)sheet.GetRow(i);
            DataRow dataRow = dt.NewRow();
            for (int j = row.FirstCellNum; j < cellCount; j++)
            {
                if (row.GetCell(j) != null)
                    dataRow[j] = row.GetCell(j).ToString();
            }
            dt.Rows.Add(dataRow);
        }
        workbook = null;
        sheet = null;
    }
    public static void ExportEasy(DataTable dtSource, string strFileName)
    {
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = (HSSFSheet)workbook.CreateSheet();
        HSSFRow dataRow = (HSSFRow)sheet.CreateRow(0);
        foreach (DataColumn column in dtSource.Columns)
        {
            dataRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
        }
        for (int i = 0; i < dtSource.Rows.Count; i++)
        {
            dataRow = (HSSFRow)sheet.CreateRow(i + 1);
            for (int j = 0; j < dtSource.Columns.Count; j++)
            {
                dataRow.CreateCell(j).SetCellValue(dtSource.Rows[i][j].ToString());
            }
        }
        using (MemoryStream ms = new MemoryStream())
        {
            using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
            {
                workbook.Write(fs);
            }
        }
    }
}

When I am run I have the following error:

ICSharpCode.SharpZipLib.Zip.ZipException: 'Cannot find central directory'

what did I suppose to do?

NPUI work only with .xlsx extension? I have the only .xls extension for the excel document. But where I run the program with .xlsx extension I have other error :

System.IO.InvalidDataException: 'Zip File is closed'

The both error appear on this line of code : XSSFWorkbook workbook = new XSSFWorkbook(path);

Ionut
  • 47
  • 7
  • Are you sure it's that line? HSSF is for xls, XSSF is for xlsx. So if you don't have any xlsx maybe your XSSF code is wrong. – Rup Oct 24 '18 at 14:08
  • That's your problem then: you need to open .xls files with HSSFWorkbook not XSSF. (Alternatively there's WorkbookFactory.Create which will autodetect and open with the right one in case you ever need that, and then you work with the interfaces not the HSSF or XSSF types.) – Rup Oct 24 '18 at 15:19
  • I change now XSSF to HSSF and the first error is gone. Now appear the second error:System.IO.InvalidDataException: 'Zip File is closed' – Ionut Oct 24 '18 at 15:37
  • xlsx files are zip files but xls files are not. So there shouldn't be any zipping or unzipping here anymore. Do you have a stack trace for that error? – Rup Oct 24 '18 at 15:39
  • Yea, should I deleted? – Ionut Oct 24 '18 at 15:51
  • I don't understand sorry. Yes you have a stack trace, but you want to delete the stack trace? I meant read down the stack trace to try and understand what NPOI was trying to unzip, because I don't think it should be unzipping anything anymore. If I had to guess I'd say it was trying to reuse an object to re-read the same file, but I can't see why that would be happening. – Rup Oct 24 '18 at 15:57
  • I have one more question. When I use this code XSSFWorkbook workbook = new XSSFWorkbook(path); is ok, but where I use HSSFWorkbook workbook = new HSSFWorkbook(path); he return a error, he tell me cannot convert string to NPOI.HSSF.MOdel.InternalWorkbook, so now how can I pass the path? Is there a special method for the path? – Ionut Oct 24 '18 at 16:06
  • From [here](https://stackoverflow.com/q/5855813/243245) it looks like it wants you to open a filestream and then give the constructor that instead of the filename. – Rup Oct 24 '18 at 16:10
  • Thank you very much for the help. My day of work is over. I will inform you tomorrow of the result. – Ionut Oct 24 '18 at 16:14
  • I have modified the code and now it work, but he give me other error on the other line – Ionut Oct 25 '18 at 08:32

1 Answers1

0

This is the modified that I do on the code:

private static void MergeData(string path, DataTable dt)
    {
        // HSSFWorkbook workbook = new HSSFWorkbook(path);
        HSSFWorkbook workbook;
        using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read))
        {
            workbook = new HSSFWorkbook();
        }
        HSSFSheet sheet = (HSSFSheet)workbook.GetSheetAt(0);
        HSSFRow headerRow = (HSSFRow)sheet.GetRow(0);
        int cellCount = headerRow.LastCellNum;
        if (dt.Rows.Count == 0)
        {
            for (int i = headerRow.FirstCellNum; i < cellCount; i++)
            {
                DataColumn column = new DataColumn(headerRow.GetCell(i).StringCellValue);
                dt.Columns.Add(column);
            }
        }
        else
        {
        }

        int rowCount = sheet.LastRowNum + 1;
        for (int i = (sheet.FirstRowNum + 1); i < rowCount; i++)
        {
            HSSFRow row = (HSSFRow)sheet.GetRow(i);
            DataRow dataRow = dt.NewRow();
            for (int j = row.FirstCellNum; j < cellCount; j++)
            {
                if (row.GetCell(j) != null)
                    dataRow[j] = row.GetCell(j).ToString();
            }
            dt.Rows.Add(dataRow);
        }
        workbook = null;
        sheet = null;
    }

Now at this line of code : `

 HSSFSheet sheet = (HSSFSheet)workbook.GetSheetAt(0);

he tell me System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index'. I read about this error and I know to initializate the index or create one, I tried that too, but no effect. What I do wrong or maybe where suppose to initializate the index? Rest of the code is the same as the previos panel, only this void I modified to Merge .xls document.

Ionut
  • 47
  • 7
  • `workbook = new HSSFWorkbook();` should be `new HSSFWorkbook(file)`. Then there should be a sheet that you've read in. – Rup Oct 25 '18 at 08:42
  • It work for that error, but than I receive this :**System.ArgumentException: 'The supplied POIFSFileSystem does not contain a BIFF8 'Workbook' entry. Is it really an excel file?'** on this line of code 'workbook = new HSSFWorkbook(file);' – Ionut Oct 25 '18 at 09:12
  • With . xlsx extension if I change to XSSF work ang I can merge now my excel document, but I have any .xlsx file, I have only . xls file and with HSSF he return this error:System.ArgumentException: 'The supplied POIFSFileSystem does not contain a BIFF8 'Workbook' entry. Is it really an excel file? – Ionut Oct 25 '18 at 09:52
  • I can't see your file so I can't help you with that sorry. Sometimes you'll find websites will give you an Excel export that's really an HTML file saved with an XLS extension because Excel will happily open that, but NPOI wouldn't - is that what you've got here? – Rup Oct 25 '18 at 09:55
  • Maybe , my excel. xls file are generate by a program and he generate .xls file on a server. For merge I have to copy all .xls file and move to my computer and then run the program to do the merge. When I add to the computer the .xls file they open implicit with the Microsoft Excel, but it is possible that program to generate in HTML format because on the server I don't have Excel Instal. – Ionut Oct 25 '18 at 10:07
  • Yea, you are right. I test now with some Excel .xls file create by me and I can merge them with NPOI in one Excel... so that mean my excel file are HTML... so how can I merge them in one file? And I tried with WorkbookFactory.Create and the result is the same, xlsx and xls created by me can merge but the xls file who I need to merge, same error – Ionut Oct 25 '18 at 13:47