Reputation: 6042
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?
Upvotes: 2
Views: 3503
Reputation: 6042
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
Upvotes: 2