我正在使用一个SQL DB,它将Excel文件(以及其他文件类型,如PDF)存储为二进制数据。我使用以下代码将这些文件解压缩到文件系统中。
问题: PDF文件就好了。但对于Excel,文件会被创建,当我尝试打开它们时,它们会崩溃或只是给我垃圾文本。
我正在使用此代码中的代码来编写此应用程序以检索文件。这段代码使用OpenMcdf,我不完全理解,因为我找不到有用的在线文档。
//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);
}
有什么想法在这里发生了什么?为什么excel损坏了?尽管经过数小时的搜索,我在网上找不到很多东西!
任何想法,建议或解决方案都将受到赞赏。
由于
答案 0 :(得分:0)
按如下方式更改SaveToDisk逻辑:
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;
}
}