【问题标题】:How can I enable the "Sharing" options on Excel workbooks?如何在 Excel 工作簿上启用“共享”选项?
【发布时间】:2012-10-27 15:51:48
【问题描述】:

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

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

编辑:根据some old pages from 2009,OpenXML 无法操作受保护文件是有限制的。但是,这也适用于共享吗?

【问题讨论】:

    标签: c# .net excel openxml closedxml


    【解决方案1】:

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

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

    2. WorkbookRevisionHeaderPart 添加到您的 Excel 文档中。添加Headers 集合 到部分。在这个集合中,Excel 将存储对历史、版本和修订的引用 信息。将第一个元素 (Header) 添加到包含 SheetIdMap(用于跟踪修订记录)。在下面的代码示例中 我已经添加了文档中包含的所有工作表。 此外,将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;
    }
    

    【讨论】:

    • 好的哇。非常感谢你做的这些。我会尽快尝试!
    • 这真的很好用!我对网络上的不同用户进行了尝试,所有更改都同时保存。如果我想摆脱共享,我可以只删除修订标题部分,还是应该删除您在此处创建的所有内容?
    • @Joe:我认为您应该删除所有内容。但我没有测试它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-01
    • 2015-06-06
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多