简体   繁体   中英

Setting DefinedNames in OpenXML to set Print Titles for all worksheets in Excel

My end aim is to programatically set Excel's "Print Titles" value of Page Setup for all worksheets in my document.

Initially I tried looking at using the SpreadsheetPrintingParts object ( based on this question ) - however, that requires generating a base 64 string, which seemingly has to come from an exisiting file. (I am generating my spreadsheet from scratch.)

This post then taught me that I could set "Print_Titles" as a defined name on the row I needed instead. I've been attempting to do that programatically, but this seems to corrupt all my files.

My code:

        var definedNamesCol = new DefinedNames();    //Create the collection
        var definedName = new DefinedName() { Name = "_xlnm.Print_Titles", Text = "\'SheetName\'!$2:$2", LocalSheetId = (UInt32) (_nextSheetId - 1) };       // Create a new range

        definedNamesCol.Append(definedName);                  // Add it to the collection

        _workbookPart.Workbook.Append(definedNamesCol);

I've also looked with the OpenXML productivity tool which suggests: (Essentially identical)

        DefinedNames definedNames1 = new DefinedNames();
        DefinedName definedName1 = new DefinedName(){ Name = "_xlnm.Print_Titles", LocalSheetId = (UInt32Value)0U };
        definedName1.Text = "\'SheetName\'!$2:$2";

        definedNames1.Append(definedName1)

I've also tried setting the Xlm property on DefinedName but the file then opens with an error that it contains Macro's in a Macro-Free file, which isn't what I think I want to do.

A (simplified) version of what I'm generating in workbook.xml:

<?xml version="1.0" encoding="utf-8"?>
<x:workbook xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <x:sheets>
        <x:sheet name="ABBEY" sheetId="1" r:id="R2f5447238bc94fa4" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" />
    </x:sheets>
    <x:definedNames>
        <x:definedName name="_xlnm.Print_Titles" localSheetId="0">'SheetName'!$2:$2</x:definedName>
    </x:definedNames>
</x:workbook>

Is there a better way to approach the problem? Or is my intention right, and it's a misunderstanding of the method somewhere else?

The above code was within a CreateWorksheet method, so was being called for each sheet. In the resulting workbook.xml file, this was then creating multiple definedNames objects, when there should only be a single definedNames object containing multiple definedNames .

I resolved the problem using this code:

        var definedName = new DefinedName() { Name = "_xlnm.Print_Titles", Text = "\'Sheet Name\'!$2:$2", LocalSheetId = (UInt32) (_nextSheetId - 1) };       // Create a new range

        if (_workbookPart.Workbook.DefinedNames == null)
        {
         var definedNamesCol = new DefinedNames();
        _workbookPart.Workbook.Append(definedNamesCol);
        }

        _workbookPart.Workbook.DefinedNames.Append(definedName);                  // Add it to the collection

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM