EOF In Header exception when reading .xlsm

Jun 24, 2013 at 3:42 PM
I'm getting an EOF in Header exception when opening a XLSM file and initializing a XSSFWorkBook(Stream) object with the 2.0 beta version of NPOI. Below is a stack trace. Has anyone seen this before?

Stack trace:
at ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputBuffer.ReadLeByte()
at ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputBuffer.ReadLeShort()
at ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputBuffer.ReadLeInt()
at ICSharpCode.SharpZipLib.Zip.ZipInputStream.GetNextEntry()
at NPOI.OpenXml4Net.Util.ZipInputStreamZipEntrySource..ctor(ZipInputStream inp)
at NPOI.OpenXml4Net.OPC.ZipPackage..ctor(Stream in1, PackageAccess access)
at NPOI.OpenXml4Net.OPC.OPCPackage.Open(Stream in1)
at NPOI.Util.PackageHelper.Open(Stream is1)
at NPOI.XSSF.UserModel.XSSFWorkbook..ctor(Stream is1)
at Magnolia.FileUtilities.ExcelWrapper.openWorkbook() in C:\Development\Magnolia\Magnolia\FileUtilities\ExcelWrapper.cs:line 109
at Magnolia.FileUtilities.ExcelWrapper..ctor(String pathAndFile) in C:\Development\Magnolia\Magnolia\FileUtilities\ExcelWrapper.cs:line 91
at DocumentManager.MBGFE.ImportVBT.importVBTFile(String pathAndFile) in C:\Documents and Settings\tclaaso\my documents\visual studio 2010\Projects\DocumentManager\DocumentManager\MBGFE\ImportVBT.aspx.cs:line 454
at DocumentManager.MBGFE.ImportVBT.onImportButtonClicked(Object sender, EventArgs e) in C:\Documents and Settings\tclaaso\my documents\visual studio 2010\Projects\DocumentManager\DocumentManager\MBGFE\ImportVBT.aspx.cs:line 486
Jul 1, 2013 at 3:41 PM
FYI - this problem was resolved, and it was a problem on my part, not on the NPOI library.
Jul 22, 2013 at 12:05 PM
Hi,
how do you solve this ? I have exactly the same problem creating a XSSFWorkbook reading from stream (xlsx source):
Here I'm reading from posted file in SharePoint (properties are SPItemEventProperties). There is no problem if I return a HSSFWorkbook with the same filestream.
 Stream fileStream = null;
            HttpPostedFile postedFile = null;
            string searchForFileName = Path.GetFileName(properties.BeforeUrl);
            HttpFileCollection collection = _context.Request.Files;
            for (int i = 0; i < collection.Count; i++)
            {
                postedFile = collection[i];
                if (searchForFileName.Equals(
                  Path.GetFileName(postedFile.FileName), StringComparison.OrdinalIgnoreCase))
                {
                    fileStream = postedFile.InputStream;
                    fileStream.Position = 0;
                    byte[] fileContents = new byte[postedFile.ContentLength];
                    fileStream.Read(fileContents, 0, postedFile.ContentLength);
                }
            }

            if (postedFile.FileName.ToLowerInvariant().EndsWith("xlsx"))
            {
                return new XSSFWorkbook(fileStream);

            }
Jul 22, 2013 at 3:26 PM
The context for my error is different than yours - I was not trying to open a file...I was creating one.

I can say that when I initialize a XSSFWorkbook (and get the underlying filestream), I don't use Stream.Read(). Why are you pushing the stream into a byte array when you already have the stream in the postedFile.InputStream?

In any event, this version of NPOI does seem a little temperamental...it seems like the interaction between XSSFWorkbook and the FileStream is a bit fragile...

I would try to initialize the XSSFWorkbook either by removing the lines of code where you initialize the byte array and read the stream into it...or, perhaps, consider returning the XSSFWorkbook using the PathAndFile constructor -- postedFile.FileName (or whatever attribute provides the entire path of the source file)...so, for instance, return new XSSFWorkbook(postedFile.FileName).

If you're having security issues or other technical issues directly opening postedFile.FileName, you could do a File.Copy(postedFile.FileName, TARGET_LOCATION)...then return new XSSFWorkbook(TARGET_LOCATION)


Good luck.
Jul 23, 2013 at 7:22 AM
Thank you @timclaason,
yes, you're right with the stream reading, thats the problem of code re-using. Anyway I'm trying other XSSFWorkBook() with no luck, for example this with NPOI.OpenXml4Net.OPC.OPCPackage.
try
{
    HttpPostedFile postedFile = null;
    string searchForFileName = Path.GetFileName(properties.BeforeUrl);
    HttpFileCollection collection = _context.Request.Files;
    NPOI.OpenXml4Net.OPC.OPCPackage xlsxPackage = null;

    for (int i = 0; i < collection.Count; i++)
    {
        postedFile = collection[i];
        if (searchForFileName.Equals(Path.GetFileName(postedFile.FileName), StringComparison.OrdinalIgnoreCase))
        {
            xlsxPackage = NPOI.OpenXml4Net.OPC.OPCPackage.Open(postedFile.InputStream);
        }
    }
    return new XSSFWorkbook(xlsxPackage);
}
catch (Exception ex)
{
    return null;
    throw ex;
}
I will try with other different constructors, thanks.
Jul 23, 2013 at 10:39 AM
FYI :

this code works in order to read a file into a XSSFWorkbook:

private IWorkbook InitializeAddingWorkbook(HttpPostedFile postedFile)
 {
    Stream fileStream = postedFile.InputStream;

    byte[] fileContents = new byte[postedFile.ContentLength];
    fileStream.Read(fileContents, 0, postedFile.ContentLength);
    fileStream.Position = 0; // <---- remember to rewind the stream

    return new XSSFWorkbook(fileStream);

}
Just remember that XSSFWorkbook needs a zip library to decode zipped xml, and the stream passed to the unzipper needs to be at 0 position.
When fileStream.Read( ) reads, the stream keeps positioned at end, so when unzipper needs to read it gets "EOF".

Thanks for your help.

Luis.
Jul 23, 2013 at 2:09 PM
That need to rewind seems sort of defect-ish...I wonder if it makes sense in this project to reset the position of the stream during object initialization...in any event, hopefully this message thread will help someone someday. Good stuff to know.