Excel – Read only or Lock the particular cells or rows using open xml sdk

excelexport-to-excelopenxmlopenxml-sdk

I am using open xml sdk to export excel. I get the excel file and copying that file to another place and then I'm inserting new rows with the data.

I should make that rows as read only (or I've to lock) using open xml sdk..

How to do that ?

Best Answer

I've referred the following link Excel File Password Protection with Open XML SDK.

Here I gave you full code to open the file from directory and insert cells. Here I've inserted only one cell. You can insert as you want. Here I've inserted locked cells. Find this one, it'll very helpful to you..

Note : Here I've mentioned the code only to read the existing file and insert the row and cells and lock the cells which have been inserted manually

Thank you.

// To read the xlsx file..
Package spreadsheetPackage = Package.Open(destinationFile, FileMode.Open, FileAccess.ReadWrite);

// create a document
using(var document = SpreadsheetDocument.Open(spreadsheetPackage)) {

    var workbookPart = document.WorkbookPart;
    //var workbook = workbookPart.Workbook;

    var sheet = workbookPart.Workbook.Descendants < Sheet > ().FirstOrDefault();
    Worksheet ws = ((WorksheetPart)(workbookPart.GetPartById(sheet.Id))).Worksheet;
    SheetData sheetData = ws.GetFirstChild < SheetData > ();

    if (sheet == null || sheetData == null) throw new Exception("No sheet found in the template file");

    int rowIndex;

    var worksheetPart = (WorksheetPart) workbookPart.GetPartById(sheet.Id);
    var rows = worksheetPart.Worksheet.Descendants < Row > ();
    DocumentFormat.OpenXml.Spreadsheet.Cell cell = new Cell();

    // Getting row index from the web config..
    if (!int.TryParse(WebConfigurationManager.AppSettings["BasReportRowIndex"].ToString(), out rowIndex)) throw new Exception("Mention template row index in the configuration file");

    // Create Cell format .. It's necessary to lock the cell
    CellFormat lockFormat = new CellFormat() {
        ApplyProtection = true,
        Protection = new Protection() {
            Locked = true
        }
    };
    WorkbookStylesPart sp = workbookPart.GetPartsOfType < WorkbookStylesPart > ().FirstOrDefault();

    if (sp == null) sp = worksheetPart.AddNewPart < WorkbookStylesPart > ();

    sp.Stylesheet.CellFormats.AppendChild < CellFormat > (lockFormat);
    sp.Stylesheet.CellFormats.Count = UInt32Value.FromUInt32((uint) sp.Stylesheet.CellFormats.ChildElements.Count);
    sp.Stylesheet.Save();

    foreach(WeekSummary summary in report.Summary) {
        DocumentFormat.OpenXml.Spreadsheet.Row row = new DocumentFormat.OpenXml.Spreadsheet.Row();

        // Before insert Row we've to mention the index where the row must be inserted
        row.RowIndex = (UInt32) rowIndex++;

        row.AppendChild < Cell > (new Cell() {
            DataType = CellValues.String,
            CellValue = new CellValue(summary.name ? ?""),
            StyleIndex = 0
        });

        // Append the row to sheet data.. 
        sheetData.AppendChild < Row > (row);
    }
    // Till the line It's only to create and insert row..

    // Now we've to mention the sheet protection. It's necessary for the whole sheet. Then only cells will be locked
    SheetProtection sheetProtection = new SheetProtection();
    sheetProtection.Password = "CC";
    // these are the "default" Excel settings when you do a normal protect
    sheetProtection.Sheet = true;
    sheetProtection.Objects = true;
    sheetProtection.Scenarios = true;

    // After the following lines, the cell will be locked...
    bool bFound = false;
    OpenXmlElement oxe = worksheetPart.Worksheet.FirstChild;
    foreach(var child in worksheetPart.Worksheet.ChildElements) {
        // start with SheetData because it's a required child element
        if (child is SheetData || child is SheetCalculationProperties) {
            oxe = child;
            bFound = true;
        }
    }

    if (bFound) worksheetPart.Worksheet.InsertAfter(sheetProtection, oxe);
    else worksheetPart.Worksheet.PrependChild(sheetProtection);

    worksheetPart.Worksheet.Save();
}