1

是否可以通过OpenXMLClosedXML在 excel 文档上启用“共享” ?或者任何其他库,如果它可以提供帮助......我相信这通常是在您保存文档时执行的(至少它在 VBA 中是这样工作的),但我找不到如何在 C# 中指定保存参数。

我想避免使用 InterOp,因为我可能会通过网络在多个文件上批处理这个过程。

编辑:根据2009 的一些旧页面,OpenXML 无法操作受保护的文件存在限制。但是,这也适用于共享吗?

4

1 回答 1

3

没有很好地记录使用 OpenXML SDK 共享 Excel 文档。我做了一些测试,发现可以使用 OpenXML SDK 在 Excel 文档上启用共享。启用共享需要以下步骤:

  1. WorkbookUserDataPart在 Excel 文档中添加一个。向部件添加一个空集合Users。在此集合中,Excel 存储当前打开此共享工作簿的所有用户。

  2. WorkbookRevisionHeaderPart在 Excel 文档中添加一个。向零件添加一个Headers集合。在这个集合中,Excel 将存储对历史、版本和修订信息的引用。将第一个元素 ( Header) 添加到包含 SheetIdMap(用于跟踪修订记录)的集合中。在下面的代码示例中,我添加了文档中包含的所有工作表。此外,将 a 添加WorkbookRevisionLogPart到工作簿的修订标题部分。在日志部分中存储了对文档所做的修订列表。

下面的代码示例显示了如何在 Excel 文档上启用共享。该代码还检查文档是否已启用共享。

在启用共享之前,您应该创建原始文档的备份。

using (SpreadsheetDocument sd = SpreadsheetDocument.Open("c:\\temp\\enable_sharing.xlsx", true))
{
  WorkbookPart workbookPart = sd.WorkbookPart;

  if (workbookPart.GetPartsCountOfType<WorkbookRevisionHeaderPart>() != 0)
  {
    Console.Out.WriteLine("Excel document already shared!");
    return;
  }

  // Create user data part if it does not exist.
  if (workbookPart.GetPartsCountOfType<WorkbookUserDataPart>() == 0)
  {
    Console.Out.WriteLine("Adding user data part");
    WorkbookUserDataPart workbookUserDataPart = workbookPart.AddNewPart<WorkbookUserDataPart>();

    Users users = new Users() { Count = (UInt32Value)0U };
    users.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");

    workbookUserDataPart.Users = users;
  }

  // Create revision header part and revision log part.
  WorkbookRevisionHeaderPart workbookRevisonHeaderPart = workbookPart.AddNewPart<WorkbookRevisionHeaderPart>();

  WorkbookRevisionLogPart workbookRevisionLogPart = workbookRevisonHeaderPart.AddNewPart<WorkbookRevisionLogPart>();

  // Create empty collection of revisions.
  Revisions revisions = new Revisions();
  revisions.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");

  workbookRevisionLogPart.Revisions = revisions;

  string lastSetOfRevisionsGuid = Guid.NewGuid().ToString("B");

  // Create headers collection (references to history, revisions)
  Headers headers = new Headers() { Guid = lastSetOfRevisionsGuid };
  headers.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");

  int worksheetPartsCount = workbookPart.GetPartsCountOfType<WorksheetPart>();                        

  // Create first element in headers collection
  // which contains the SheetIdMap.
  Header header = new Header() { Guid = lastSetOfRevisionsGuid, DateTime = DateTime.Now, 
                                 MaxSheetId = (UInt32Value)(uint)worksheetPartsCount+1, UserName = "hans", Id = "rId1" };

  // Create the list of sheet IDs that are used for tracking
  // revision records. For every worksheet in the document
  // create one SheetId.
  SheetIdMap sheetIdMap = new SheetIdMap() { Count = (UInt32Value)(uint)worksheetPartsCount };

  for (uint i = 1; i <= worksheetPartsCount; i++)
  {
    SheetId sheetId = new SheetId() { Val = (UInt32Value)i };

    sheetIdMap.Append(sheetId);
  }        

  header.Append(sheetIdMap);
  headers.Append(header);

  workbookRevisonHeaderPart.Headers = headers;
}
于 2012-11-01T09:01:57.403 回答