Excel-bestanden zijn beschadigd als ze worden opgehaald uit SQL DB

Ik werk met een SQL-database die Excel-bestanden (samen met andere bestandstypen zoals PDF) opslaat als binaire gegevens. Ik gebruik de volgende code om deze bestanden naar het bestandssysteem te extraheren.

Het probleem: PDF-bestanden komen er goed uit. Maar voor Excel worden de bestanden aangemaakt en wanneer ik ze probeer te openen, crashen ze of geven ze me gewoon vuilnis.

Ik gebruik deze code van de vorige gast die deze app heeft geschreven voor het ophalen van bestanden. Deze code maakt gebruik van OpenMcdf die ik niet volledig begrijp, omdat ik er geen bruikbare online documentatie voor kon vinden.

//execution starts here
public override void SaveToDisk()
{

    byte[] keys = { (byte)0xd0, (byte)0xcf };


    //Searches through m_RawOleObject for combination of 'keys'
    int offset = Utils.SearchBytes(m_RawOleObject, keys); //returns '60' in case of Excel and '66' in case of Pdf

    //m_RawOleOjbect contains the data from the sqlDataReader (the binary data from the column.)
    m_RawOleObject = strip(m_RawOleObject, offset);

    MemoryStream ms = new MemoryStream(m_RawOleObject);
    CompoundFile cf = new CompoundFile(ms);
    GetStorageByName(cf.RootStorage, m_StorageName);

    if (Storage != null)
    {
        if (Storage is CFStream)
        {
            m_RawOleObject = (Storage as CFStream).GetData();
        }
        m_filename = System.IO.Path.Combine(STOREPATH, Utils.CombineFilenameWithExtension(Filename, m_extension));

        WriteToFile(m_filename, m_RawOleObject);
    }

}

protected void WriteToFile(string fn, byte[] obj)
{
    fn = GetNextAvailableFilename(fn, 0);
    FileStream fs = new FileStream(fn, FileMode.Create);
    BinaryWriter writer = new BinaryWriter(fs);
    writer.Write(obj);
    writer.Close();
    fs.Close();
    fs.Dispose();
}


protected void GetStorageByName(CFStorage cfs, string name)
{
    VisitedEntryAction va = delegate(CFItem target)
    {
        if (target is CFStorage)
        {
            GetStorageByName((CFStorage)target, name);
        }
        else
        {
            if (target.Name == name)
                Storage = target;
        }
    };

    //Visit NON-recursively (first level only)
    cfs.VisitEntries(va, false);
}

Om het even welke ideeën wat hier gebeurt? waarom zijn de excels beschadigd? Ik kon niet veel online vinden ondanks uren zoeken!

eventuele ideeën, suggesties of oplossingen worden op prijs gesteld.

Bedankt

0
WAT database en welke versie ?? SQL is slechts de gestructureerde querytaal - een taal die wordt gebruikt door veel databasesystemen - SQL is NOT een databaseproduct ... dit soort dingen is vaak leverancierspecifiek - dus we moeten echt weten welk databasesysteem u gebruikt ....
toegevoegd de auteur marc_s, de bron
Eerste gok zou SQL Server zijn, gezien de vermelding van SqlDataReader
toegevoegd de auteur sq33G, de bron
goed..Ik dacht dat 'SQL DB' duidelijk Microsoft SQL Server aangeeft !! en het is 2005
toegevoegd de auteur user732528, de bron

1 antwoord

Wijzig uw SaveToDisk-logica als volgt:

public override void SaveToDisk()
{
    byte[] keys = { (byte)0xd0, (byte)0xcf, (byte)0x11, (byte)0xe0, (byte)0xa1, (byte)0xb1, (byte)0x1a, (byte)0xe1 };
    int offset = Utils.SearchBytes(m_RawOleObject, keys);
    using (MemoryStream ms = new MemoryStream(strip(m_RawOleObject, offset)))
    {
        CompoundFile cf = new CompoundFile(ms, UpdateMode.ReadOnly, true, true);
        m_filename = GetNextAvailableFilename(System.IO.Path.Combine(STOREPATH, Utils.CombineFilenameWithExtension(Filename, m_extension)), 0);
        using (var fs = new FileStream(m_filename, FileMode.Create))
        {
            cf.Save(fs);
            cf.Close();
        }
    }

    //Workbook would be saved as hidden in previous step
    Microsoft.Office.Interop.Excel.Application xlApp = null;
    Microsoft.Office.Interop.Excel.Workbook xlWb = null;
    try
    {
        xlApp = new Microsoft.Office.Interop.Excel.Application();
        xlWb = xlApp.Workbooks.Open(m_filename);
        xlWb.CheckCompatibility = false;

        foreach (Window wn in xlApp.Windows)
        {
            wn.Visible = true;
        }
        xlWb.Save();
        xlWb.Close();
    }
    catch (Exception e)
    {
        //TODO: Log error and continue
    }
    finally
    {
        if (xlWb != null)
            Marshal.ReleaseComObject(xlWb);
        if (xlApp != null)
            Marshal.ReleaseComObject(xlApp);
        xlApp = null;
    }
}
0
toegevoegd