How can I set the \"Print Titles\" property of a spreadsheet with OpenXML, to have a row show at the top of every printed page?
The property is directly saved in the SpreadsheetPrintingParts
object, however, this doesn't appear to be fully integrated into OpenXML as of yet, and requires passing a base64 string in to the variable. (see here) The content of this string appears to be tied to the machine the file is opened on, which didn't work for my implementation - I wasn't able to create a non-corrupt file through SpreadsheetPrintingParts.FeedData()
.
Instead, I found this post which stated giving the row the defined name "Print_Titles" has the same effect. I was then able to create a defined name through OpenXML with the following code:
public void SetPrintTitleRows(int startRowIndex, int? endRowIndex = null)
{
var localSheetId = _localsheetId++; //LocalSheetIds are 0-indexed.
var definedName = new DefinedName
{
Name = "_xlnm.Print_Titles",
LocalSheetId = localSheetId,
Text = String.Format("\'{0}\'!${1}:${2}", _sheetName, startRowIndex, endRowIndex ?? startRowIndex)
};
if (_workbookPart.Workbook.DefinedNames == null)
{
var definedNamesCol = new DefinedNames();
_workbookPart.Workbook.Append(definedNamesCol);
}
_workbookPart.Workbook.DefinedNames.Append(definedName);
}
Points to note:
DefinedName.LocalSheetId
is zero-indexed, as opposed to Sheet.Id
which is 1-indexedDefinedNames
is once per workbook, but can contain multiple DefinedName
objects for different sheets.