目前,我正在通过传递MemoryStream
参数,使用Open XML的SpreadsheetDocument
类创建一个新的Excel文档。我现在需要在这个mem
对象上设置密码,但我尝试过的东西似乎不起作用。 Excel文档无需输入密码即可打开。
以下是我到目前为止所尝试的内容(MemoryStream
是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"
}
}
我也试过以下但没有成功:
{{1}}
我错过了什么?
答案 0 :(得分:3)
Openxml工作表保护密码输入数据类型为" HexBinaryValue"。所以输入密码要从字符串转换为六进制二进制文件。
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();
}
答案 1 :(得分:0)
好的,不完全是我想做的事情,但我最终放弃了Open XML SDK并使用Office.Interop程序集来保护文档。首先使用Open XML的原因是因为似乎无法使用流打开Interop工作簿,它需要一个实际的文件。
答案 2 :(得分: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());
}
}