【发布时间】:2017-07-31 22:36:45
【问题描述】:
我将 Excel 文件作为内存流发送,对其进行编辑,然后将它们发送回浏览器,以便它们在客户端办公程序 (Microsoft Excel) 中打开。在编辑过程中,我在工作簿中的所有 Excel 工作表上添加页脚。大多数情况下,页脚的插入都可以正常工作,但是如果我编辑的 Excel 文件中有许多带有图表等的“复杂”工作表,则它会失败。这是我用来插入页脚的代码
// Adds footer to all sheets in the workbook except the one inserted by code
private static void AddFooterToAllSheets(SpreadsheetDocument spreadSheetDocument, string footerText, string sheetTitle)
{
var workbookPart = spreadSheetDocument.WorkbookPart;
var workbook = spreadSheetDocument.WorkbookPart.Workbook;
var sheetIndex = 0;
//variable worksheetpart is not used in code, but added here because of looping
foreach (var worksheetpart in workbook.WorkbookPart.WorksheetParts)
{
string sheetName = workbookPart.Workbook.Descendants<Sheet>().ElementAt(sheetIndex).Name;
if (sheetName.Equals(sheetTitle))
{
sheetIndex++;
continue;
}
InsertHeaderFooter(spreadSheetDocument, sheetName, footerText, HeaderType.AllFooter);
sheetIndex++;
}
}
public static void InsertHeaderFooter(SpreadsheetDocument document, string sheetName, string textToInsert, HeaderType type)
{
var wbPart = document.WorkbookPart;
// Find the sheet with the supplied name, and then use
// that Sheet object to retrieve a reference to
// the appropriate worksheet.
var theSheet = wbPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetName).FirstOrDefault();
if (theSheet == null)
{
return;
}
var wsPart = (WorksheetPart)(wbPart.GetPartById(theSheet.Id));
var ws = wsPart.Worksheet;
// Worksheet is nothing? You have a damaged workbook!
if (ws == null)
{
return;
}
// Retrieve a reference to the header/footer node, if it exists.
var hf = ws.Descendants<HeaderFooter>().FirstOrDefault();
if (hf == null)
{
hf = new HeaderFooter();
ws.AppendChild<HeaderFooter>(hf);
}
// The HeaderFooter node should be there, at this point!
if (hf != null)
{
// You've found the node. Now add the header or footer.
// Deal with the attributes first:
switch (type)
{
case HeaderType.EvenHeader:
case HeaderType.EvenFooter:
case HeaderType.OddHeader:
case HeaderType.OddFooter:
// Even or odd only? Add a differentOddEven attribute and set
// it to "1".
hf.DifferentOddEven = true;
break;
case HeaderType.FirstFooter:
case HeaderType.FirstHeader:
hf.DifferentFirst = true;
break;
}
switch (type)
{
// This code creates new header elements, even if they
// already exist. Either way, you end up with a
// "fresh" element.
case HeaderType.AllHeader:
hf.EvenHeader = new EvenHeader { Text = textToInsert };
hf.OddHeader = new OddHeader { Text = textToInsert };
break;
case HeaderType.AllFooter:
hf.EvenFooter = new EvenFooter { Text = textToInsert };
hf.OddFooter = new OddFooter { Text = textToInsert };
break;
case HeaderType.EvenFooter:
hf.EvenFooter = new EvenFooter { Text = textToInsert };
break;
case HeaderType.EvenHeader:
hf.EvenHeader = new EvenHeader { Text = textToInsert };
break;
case HeaderType.OddFooter:
hf.OddFooter = new OddFooter { Text = textToInsert };
break;
case HeaderType.OddHeader:
hf.OddHeader = new OddHeader { Text = textToInsert };
break;
case HeaderType.FirstHeader:
hf.FirstHeader = new FirstHeader { Text = textToInsert };
break;
case HeaderType.FirstFooter:
hf.FirstFooter = new FirstFooter { Text = textToInsert };
break;
}
}
ws.Save();
}
尝试打开文档时会提示我 Excel 文件已损坏。在验证损坏的文件时,我在 Open XML SDK 2.5 Productivity Tool 中遇到的错误是:
错误节点类型:工作表 错误部分:/xl/worksheets/sheet2.xml 错误节点路径:/x:worksheet[1] 相关节点类型:HeaderFooter
说明:该元素有意外的子元素“http://schemas.openxmlformats.org/spreadsheetml/2006/main:headerFooter”。
【问题讨论】:
-
“如果我编辑的 Excel 文件中有许多带有图表等的“复杂”工作表,则会失败”。我认为您的第一步是弄清楚程序何时实际失败(例如工作表包含图表),然后我们可以开始弄清楚它失败的原因
-
大多数时候我遇到“未声明'shapeId'的问题,并且在插入我的页脚后我得到元素有意外的子元素。
-
我也有同样的问题。尝试使用 cmets 打开 excel 文件时,它说文件已损坏数据。关于这个问题的任何更新?
标签: c# excel ms-office openxml openxml-sdk