MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Как определить формат файла excel?"
Answer 1005851
Как вариант, в Windows для определения, является ли файл корректным XLS-файлом, можно использовать Structured Storage API. Согласно спецификации, формат XLS - это файл формата Structured Storage, который содержит поток с именем Workbook.
MS-XLS: Excel Binary File Format Structure, пункт 2.1.2:
A file of the type specified by this document consists of storages and streams as specified in [MS-CFB]...
A workbook MUST contain the workbook stream...
Можно использовать следующий код для проверки на XLS, на основе этого правила:
using System; using System.Collections; using System.Runtime.InteropServices; namespace ConsoleApplication1 { class Program { [DllImport("ole32.dll")] static extern int StgOpenStorageEx( [MarshalAs(UnmanagedType.LPWStr)] string pwcsName, uint grfMode, uint stgfmt, uint grfAttrs, IntPtr pStgOptions, IntPtr reserved2, [In] ref Guid riid, out IStorage ppObjectOpen); const uint STGM_DIRECT = 0; const uint STGM_READ = 0; const uint STGM_SHARE_EXCLUSIVE = 0x10; const uint STGFMT_STORAGE = 0; const uint PID_FIRST_USABLE = 2; const uint STGC_DEFAULT = 0; [Guid("0000000B-0000-0000-C000-000000000046")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IStorage { void a(); [PreserveSig] int OpenStream(string pwcsName, IntPtr reserved1, uint grfMode, uint reserved2, [MarshalAs(UnmanagedType.Interface)] out object ppstm); void CreateStorage(string pwcsName, uint grfMode, uint reserved1, uint reserved2, out IStorage ppstg); void OpenStorage(string pwcsName, IStorage pstgPriority, uint grfMode, IntPtr snbExclude, uint reserved, out IStorage ppstg); void CopyTo( uint ciidExclude, Guid[] rgiidExclude, IntPtr snbExclude, IStorage pstgDest); void MoveElementTo(string pwcsName, IStorage pstgDest, string pwcsNewName, uint grfFlags); void Commit( uint grfCommitFlags); void Revert(); void b(); void DestroyElement(string pwcsName); void RenameElement(string pwcsOldName, string pwcsNewName); void c(); void SetClass( ref Guid clsid); void SetStateBits( uint grfStateBits, uint grfMask); void d(); } public static bool IsXLS(string path) { IStorage pStorage = null; object o = null; int hr; Guid guidStorage = typeof(IStorage).GUID; try { //открываем файл hr = StgOpenStorageEx(path, STGM_READ | STGM_SHARE_EXCLUSIVE, STGFMT_STORAGE, 0, IntPtr.Zero, IntPtr.Zero, ref guidStorage, out pStorage); if (hr != 0) return false; //NOT Structured storage file //открываем поток hr = pStorage.OpenStream("Workbook", IntPtr.Zero, STGM_DIRECT | STGM_READ | STGM_SHARE_EXCLUSIVE, 0, out o); return hr == 0; } finally { //освобождение ресурсов if (pStorage != null) Marshal.ReleaseComObject(pStorage); if (o != null) Marshal.ReleaseComObject(o); } } } }
Так как файл XLSX является ZIP-архивом определенной структуры, можно применить для проверки ту же логику, и воспользоваться любой библиотекой для работы с ZIP-архивами (в .NET 4.5+ есть встроенная System.IO.Compression).
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.