Welcome to OpenXML Developer Sign in | Join | Help

Protect sheets using OpenXML.

Last post 09-08-2008, 3:27 AM by Ankush Bhatia. 5 replies.
Sort Posts: Previous Next
  •  08-25-2008, 7:13 AM 3601

    Protect sheets using OpenXML.

    I am working with the OpenXML.

    How the following activities can be made possible using OpenXML SDK.

    1.Protect sheets using password
    2. Paste special (to remove all the formulae) or anything equivalent,
    3. Delete specified sheets if the worksheets contains formulaes.

    4. Usage of Excel Goal seek functionality.

    Litlle brief

    -----------

    Problem-1

    For protect sheet i researched a bit and found that one element needs to be added in corresponding sheet.xml

     

    <sheetProtection sheet="1" insertRows="0" insertHyperlinks="0" deleteColumns="0" deleteRows="0" />

    i tried by adding this element but when opening the .xlsx file it says "Converter failed to open the file."

     

    Problem-2

     

    No clue how to do paste special using OpenXML SDK.

     

    Problem-3

    To delete the specified sheet i have written the below code.

     

    public static bool DeleteSheet(string fileName, string sheetToDelete)

    {

    bool returnValue = false;

    using (SpreadsheetDocument xlDoc = SpreadsheetDocument.Open(fileName, true))

    {

    XmlDocument doc = new XmlDocument();

    doc.Load(xlDoc.WorkbookPart.GetStream());

    XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable);

    nsManager.AddNamespace("d", doc.DocumentElement.NamespaceURI);

    string searchString = string.Format("//dTongue Tiedheet[@name='{0}']", sheetToDelete);

    XmlNode node = doc.SelectSingleNode(searchString, nsManager);

    if (node != null)

    {

    XmlAttribute relationAttribute = node.Attributes["r:id"];

    if (relationAttribute != null)

    {

    string relId = relationAttribute.Value;

    xlDoc.WorkbookPart.DeletePart(relId);

    node.ParentNode.RemoveChild(node);

    Stream st = xlDoc.WorkbookPart.GetStream(FileMode.Create);

    doc.Save(st);

    returnValue = true;

    }

    }

    }

    return returnValue;

    }

    Any Help or suggestion will be greately appreciated.

    Vikas

  •  08-27-2008, 12:40 PM 3616 in reply to 3601

    Re: Protect sheets using OpenXML.

    Hello Vikas,

    Here are some suggestions:

    "Delete specified sheets if the worksheets contains formulaes"

    When you add a formula to the worksheet(s), an instance of the part type 'Calculation Chain Part' (calcChain.xml) is added to the package. It contains an ordered set of references to all cells in all worksheets in the workbook whose value is calculated from any formula.

    So if you want to delete a worksheet containing formulas, you need to delete the entries from calcChain.xml as well.

    Here is the sample code to do it: Please note that in this code  the sheetName and the id (doc1.SelectNodes("//ss:c[@i='1']", nsManager) is hardcoded. You can get this value easily using node variable and querying for the attributes.

    using (SpreadsheetDocument xlDoc = SpreadsheetDocument.Open(filePath, true))

    {

    XmlDocument doc = new XmlDocument();

    doc.Load(xlDoc.WorkbookPart.GetStream());

    XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable);

    nsManager.AddNamespace("d", doc.DocumentElement.NamespaceURI);

    string searchString = string.Format("//d:sheet[@name='{0}']", "Sheet1");

    XmlNode node = doc.SelectSingleNode(searchString, nsManager);

    if (node != null)

    {

    XmlAttribute relationAttribute = node.Attributes["r:id"];

    if (relationAttribute != null)

    {

    string relId = relationAttribute.Value;

    CalculationChainPart w = xlDoc.WorkbookPart.CalculationChainPart;

    XmlDocument doc1 = new XmlDocument();

    doc1.Load(w.GetStream());

    XmlNamespaceManager nsManager1 = new XmlNamespaceManager(doc1.NameTable);

    nsManager1.AddNamespace("ss", doc1.DocumentElement.NamespaceURI);

    XmlNodeList ss1= doc1.SelectNodes("//ss:c[@i='1']", nsManager1);

    foreach (XmlNode w1 in ss1)

    {

    w1.ParentNode.RemoveChild(w1);

    }

    MessageBox.Show(doc1.InnerXml);

    xlDoc.WorkbookPart.DeletePart(relId);

    node.ParentNode.RemoveChild(node);

    doc.Save(xlDoc.WorkbookPart.GetStream(FileMode.Create));

    doc1.Save(w.GetStream(FileMode.Create));

    }

    }

    }

     

  •  09-01-2008, 2:00 AM 3624 in reply to 3616

    Re: Protect sheets using OpenXML.

    Thanks for the reply Ankush,

    I am able to delete the sheets if a sheet is having formula,but my sheet contains some defined names also which may or may not have referenced by other sheets.

    i am getting this recovery message when i am trying to open the spreadsheet.this message i am getting this message even if i have deleted the sheets which is reffering the defined name.

    for e.g. i have a workbook of 10 sheets, which contains some user defined names also.

    'Sheet1' contains a range and a defined name 'X' has been assigned to that range. 'X' has been used by 'Sheet2' and 'Sheet3'.I am not able to delete Sheet1 even if i deletes the Sheet2 and Sheet3 by opening the worksheet from office.

    I beleive 'Sheet1' and defined name 'X' keeps some relational information some where else too and that also needs to be removed.

    1 reference i found in workbook.xml, which i deleted and saved but i did this by navigating the workbook.xml and deletes the node and saved.

    Recovery Error message while opening the Spreadsheet.

      <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    - <recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
      <logFileName>error040800_01.xml</logFileName>
      <summary>Errors were detected in file 'D:\Vikas\testdata\10ENDP1.xlsx'</summary>
    - <removedFeatures summary="Following is a list of removed features:">
      <removedFeature>Removed Feature: Named range from /xl/workbook.xml part (Workbook)</removedFeature>
      </removedFeatures>
      </recoveryLog>

     

    Any help or tip will be apprfeciated.

    Vikas

  •  09-03-2008, 1:14 AM 3640 in reply to 3624

    Re: Protect sheets using OpenXML.

    Hello Vikas,

    You need to look at 2 nodes in the workbook.xml.

    Node 1 : definedNames Node:

    If your sheet in question contains any defined names it will be recorded in this XML tag. So if you know the name of the DefinedNames then you can serach on attributes otherwise you need to loop the definedNames node and search for innerText of each node which contains your sheet name. For ex: If I have  workbook defined with 3 DefinedNames on Sheet1 and Sheet2, hen this tag will look like

    <definedNames>

      <definedName name="Range1">Sheet1!$A$1:$A$4</definedName>
      <definedName name="Range2">Sheet2!$C$2:$C$5</definedName>
      <definedName name="TestAnk">Sheet1!$A$1:$A$4</definedName>
      </definedNames>
     
    Now its up to you how you want to delete the DefinedName node.
     
     
    Node 2 : bookViews Node :
     
    This node conatains information about workbookView. Pay close attention to activeTab attribute. What it means that which worksheet is will be active when you will open this workbook. So if this attribute is not present , Sheet1 will be active, 1 means sheet2 and so on.
     
    Now if you delete sheets from workbook and the value of activeTab attribute becomes invalid, it is going to to throw the error. So you need to delete this entry as well.
     
    HTH
     
    Ankush
     

     

     

  •  09-08-2008, 3:01 AM 3663 in reply to 3640

    Re: Protect sheets using OpenXML.

    Hi Ankush,

    Thanks a lot for replying....

    But i tried this too.still some referencing is there and deletion is not getting possible.

    if some plain sheets with only values. it deletes successfully.

    Vikas

  •  09-08-2008, 3:27 AM 3664 in reply to 3663

    Re: Protect sheets using OpenXML.

    Can I have a look at your sample XLSX file.

    Thanks

    Ankush

     

     

View as RSS news feed in XML