2016-09-12 316 views
5

目前,我正在通过传递MemoryStream参数来创建一个Open XML的SpreadsheetDocument类的新Excel文档。我现在需要在这个SpreadsheetDocument对象上设置一个密码,但我所尝试的似乎没有工作。 Excel文档打开时不需要输入密码。 下面是我到目前为止已经试过(mem作为MemoryStream参数):如何使用Open XML密码保护Excel文档

using (SpreadsheetDocument spreadsheet = SpreadsheetDocument.Open(mem, true)) 
{ 
    foreach (var sheet in spreadsheet.WorkbookPart.WorksheetParts) 
    { 
     sheet.Worksheet.Append(new SheetProtection() { Password = "test" }); 
    } 
} 

我也尝试没有成功如下:

using (SpreadsheetDocument spreadsheet = SpreadsheetDocument.Open(mem, true)) 
{ 
    spreadsheet.WorkbookPart.Workbook.WorkbookProtection = new WorkbookProtection 
    { 
     LockStructure = true, 
     LockWindows = true, 
     WorkbookPassword = "test" 
    } 
} 

我在想什么吗?

+0

的[Excel文件的密码保护和Open XML SDK]可能的复制(http://stackoverflow.com/questions/15168011/excel-file-password-protection-with-open-xml-sdk) –

+0

呀,这是我从我的第一次尝试的代码示例,但没有成功。 –

+0

你有没有注意到,其他[SO帖子回答](http://stackoverflow.com/a/15281182/997668)建议调用'Save()'方法以防万一它不起作用? '//添加这个以防万一它仍然不起作用。这确保数据被保存。 //worksheet.Worksheet.Save();' 你试过了吗?这也没有帮助? – Michael

回答

0

好吧,所以不完全是我想要做的,但我最终放弃了Open XML SDK并使用Office.Interop程序集来保护文档。首先使用Open XML的原因是因为Interop工作簿看起来不​​能用流打开,它需要一个实际的文件。

0

你可以试试这个:

using (SpreadsheetDocument spreadsheet = SpreadsheetDocument.Open(mem, true)) 
{ 
    foreach (var worksheetPart in spreadsheet.WorkbookPart.WorksheetParts) 
    { 
      SheetProtection sheetProt = new SheetProtection() { Sheet = true, Objects = true, Scenarios = true, Password = "test" }; 
      worksheetPart.Worksheet.InsertAfter(sheetProt, worksheetPart.Worksheet.Descendants<SheetData>().LastOrDefault()); 
    } 
} 
3

的OpenXML表保护密码 “HexBinaryValue” 的输入数据类型。所以输入密码要从字符串转换为hexa二进制。

foreach (var worksheetPart in spreadsheet.WorkbookPart.WorksheetParts) 
    { 
     //Call the method to convert the Password string "MyPasswordfor sheet" to hexbinary type 
     string hexConvertedPassword = HexPasswordConversion("MyPasswordfor sheet"); 
//passing the Converted password to sheet protection 
      SheetProtection sheetProt = new SheetProtection() { Sheet = true, Objects = true, Scenarios = true, Password = hexConvertedPassword }; 
      worksheetPart.Worksheet.InsertAfter(sheetProt,worksheetPart.Worksheet.Descendants<SheetData>().LastOrDefault()); 
worksheetPart.Worksheet.Save(); 
    } 


/* This method will convert the string password to hexabinary value */ 
protected string HexPasswordConversion(string password) 
     { 
      byte[] passwordCharacters = System.Text.Encoding.ASCII.GetBytes(password); 
      int hash = 0; 
      if (passwordCharacters.Length > 0) 
      { 
       int charIndex = passwordCharacters.Length; 

       while (charIndex-- > 0) 
       { 
        hash = ((hash >> 14) & 0x01) | ((hash << 1) & 0x7fff); 
        hash ^= passwordCharacters[charIndex]; 
       } 
       // Main difference from spec, also hash with charcount 
       hash = ((hash >> 14) & 0x01) | ((hash << 1) & 0x7fff); 
       hash ^= passwordCharacters.Length; 
       hash ^= (0x8000 | ('N' << 8) | 'K'); 
      } 

      return Convert.ToString(hash, 16).ToUpperInvariant(); 
     } 
+0

你从哪里得到计算散列密码的算法? –