我的应用程序需要将 byte[] 保存到磁盘,问题是我知道它是一个 Excel 文件,但不知道正确的文件扩展名是什么。有没有办法从数据本身判断文件是 .xls、.xlsx 还是 .xlsm?
我最终编写了一个扩展方法来确定 Excel 文件类型。这种方法并不完美。仅当文件具有宏时,它才会正确检测 .xlsm 文件。
private static string FindType(this byte[] file)
{
using(MemoryStream ms = new MemoryStream(file))
{
var zf = new ZipArchive(ms, ZipArchiveMode.Read);
if (zf.Entries.Any(e=>e.FullName.StartsWith("xl.")))
{
if (zf.Entries.Any(e=>e.FullName.Equals("xl/vbaProject.bin", StringComparison.InvariantCultureIgnoreCase)))
return ".xlsm";
else
return ".xlsx";
}
}
return string.Empty;
}
这是一种应该有效的方法,即使 xlsm 文件没有宏。
如果您将 xlsm/xlsx 文件作为 zip 文件打开,您将看到它包含多个子文件。
filelist:
0:<ZipInfo filename='docProps/app.xml' compress_type=deflate filemode='?rw-------' file_size=177 compress_size=130>
1:<ZipInfo filename='docProps/core.xml' compress_type=deflate filemode='?rw-------' file_size=598 compress_size=265>
...
9:<ZipInfo filename='[Content_Types].xml' compress_type=deflate filemode='?rw-------' file_size=1089 compress_size=299>
如果您打开 [Content_Types].xml 一行将包含
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.ms-excel.sheet.macroEnabled.main+xml"/>
或
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
(对于 xlsx 或 xlsm 以外的类型,此完整列表可能有用 https://www.contractsfinder.service.gov.uk/apidocumentation/ResourceModel?modelName=FileType)