技术:
C#
ASP.NET Core 2.0
Excel(大多数为OpenXml,但偶尔还有旧版文档)
当前使用ExcelDataReader读取文件。
场景:
我需要在服务器上存储一些文件,以后再访问它们以进行工作。用户通过Web API上传文件,然后拨打电话要求以相同的方式完成工作。
某些用户用密码保护其Excel文件,并且要求这些文件在服务器上时仍受密码保护。
问题:
我需要检测文档是否受密码保护,以便可以使用适当的配置来访问它。
我已经在Google上进行了很多搜索,但是大部分都与Workbook.HasPassword一起使用(我认为这是Excel.Interop的一部分,我想避免添加)。我还发现this link是关于Office文档的类似问题,在该问题中,解决方案是针对文件流中各种标题数据的长清单。
理想情况下,我想要一个不需要内核的解决方案,不需要我打开文件。我不经常使用文档,因此我对下一步查找一无所知。
有什么建议吗?
答案 0 :(得分:3)
由于您已经在使用ExcelDataReader,因此请在try-catch子句中打开文件并处理InvalidPasswordException
:
bool ExcelFileRequiresPassword(Stream stream) {
try {
using (ExcelReaderFactory.CreateReader(stream)) { }
} catch (InvalidPasswordException) {
return true;
}
return false;
}
这不是很糟糕的性能。在后台,它仅检查文件中的相关标头,并处理所有复杂的BIFF,ZIP和版本控制详细信息。如果没有密码,将不会读取任何数据。
答案 1 :(得分:1)
在不打开文件的情况下,您将不会发现文件是否受密码保护。该信息在文件中(据我所知);它没有显示在文件系统中。
您应该能够使用OpenXml SDK快速了解它。创建一个不受保护的文件。复制它。打开副本并设置密码并保存。然后使用openXml“生产力工具”来区分两个文件(“比较文件”,位于工具栏上)。它应该快速定位到哪里。
答案 2 :(得分:0)
这是我添加的旧帖子,但最近我想确定电子表格是否在 C# 中受密码保护,而不使用外部库,我最终创建了以下代码。
可能有些案例和文件格式我没有找到,但我希望这能让你走上正轨。
注意:比较文本中的空格数很重要,所以在剪切和粘贴时要小心。
static bool IsExcelPasswordProtected(string strSource)
{
bool blResult = false;
if (File.Exists(strSource))
{
char[] chBuffer = new char[4096]; // The character strings usually occur within the first 2K in my testing, but just in case
TextReader trReader = new StreamReader(strSource, Encoding.UTF8, true);
// Read the buffer
trReader.ReadBlock(chBuffer, 0, chBuffer.Length);
trReader.Close();
// Remove non-printable and unicode characters, we're only interested in ASCII character set
for (int i = 0; i < chBuffer.Length; i++)
{
if ((chBuffer[i] < ' ') || (chBuffer[i] > '~')) chBuffer[i] = ' ';
}
string strBuffer = new string(chBuffer);
// .xls format files, version 97 to 2003 contains this text when password protected
if (strBuffer.Contains("M i c r o s o f t E n h a n c e d C r y p t o g r a p h i c P r o v i d e r"))
{
blResult = true;
}
// .xlsx format files contain this text when password protected
else if (strBuffer.Contains("E n c r y p t e d P a c k a g e"))
{
blResult = true;
}
// .xlsx format files contain this text when not password protected
else if (strBuffer.Contains("[Content_Types]"))
{
blResult = false;
}
// .xlsx format files contain this text when not password protected
else
{
blResult = false;
}
}
else
{
// File not found...deal with as you wish
}
return (blResult);
}