如何将Excel图表复制到新工作簿并断开外部链接
本文关键字:工作簿 断开 链接 外部 复制 Excel | 更新日期: 2023-09-27 18:22:09
我用以下代码将所有图表从一个工作簿复制到另一个工作簿:
using Excel = Microsoft.Office.Interop.Excel;
...
private static void CopyCharts(Excel.Workbook wbIn, Excel.Workbook wbOut)
{
Excel.Worksheet wsOutAfter = (Excel.Worksheet)wbOut.Sheets["Last Sheet"];
foreach (Excel.Chart c in wbIn.Charts)
{
c.Copy(Type.Missing, wsOutAfter);
}
}
每个图表都引用源工作簿("wbIn")中工作表上的数据。问题是Chart.Copy命令保留了这些链接,所以现在目标工作簿("wbOut")中的图表包含指向wbIn的外部链接。
为了去掉外部链接,我想遍历每个目标图表中的所有系列,并更新XValues和Values以指向目标数据表。到目前为止,我拥有的是:
private static void CopyCharts(Excel.Workbook wbIn, Excel.Workbook wbOut)
{
Excel.Worksheet wsOutAfter = (Excel.Worksheet)wbOut.Sheets["Plot Items"];
foreach (Excel.Chart c in wbIn.Charts)
{
string chartName = c.Name;
c.Copy(Type.Missing, wsOutAfter);
Excel.SeriesCollection sc = (Excel.SeriesCollection)c.SeriesCollection();
foreach (Excel.Series s in sc)
{
Excel.Range r = (Excel.Range)s.XValues;
// get string representing range, modify it and set corresponding
// series in wbOut.Charts.Item[chartName] to something appropriate
}
}
}
但演员阵容抛出了一个例外:
System.InvalidCastException: Unable to cast object of type 'System.Object[*]' to type 'Microsoft.Office.Interop.Excel.Range'.
如何获取和修改Series.XValues和.Values范围?
我看错了Series的成员。我需要更改的成员是Series.Formula,而不是Series.XValues和.Values。以下是我最终得到的结果,在输出工作簿中的图表上迭代,然后在它们的系列上迭代,并使用正则表达式删除外部链接文本:
private static void CopyCharts(Excel.Workbook wbIn, Excel.Workbook wbOut)
{
Excel.Worksheet wsOutAfter = (Excel.Worksheet)wbOut.Sheets["Plot Items"];
foreach (Excel.Chart c in wbIn.Charts)
{
c.Copy(Type.Missing, wsOutAfter);
}
// break external links in new charts
Regex externalLink = new Regex(@"'[" + wbIn.Name + @"']");
foreach (Excel.Chart cOut in wbOut.Charts)
{
Excel.SeriesCollection scOut = (Excel.SeriesCollection)cOut.SeriesCollection();
foreach (Excel.Series sOut in scOut)
{
string formula = sOut.Formula;
formula = externalLink.Replace(formula, "");
sOut.Formula = formula;
}
}
}
编辑:但是有更好的方法可以去除所有外部链接。它比em>更快、更全面。我只是在复制了所有的表格和图表后称之为:
private static void BreakAllExternalLinks(Excel.Workbook wbIn, Excel.Workbook wbOut)
{
Array links = (Array)wbOut.LinkSources(Excel.XlLink.xlExcelLinks);
foreach (object o in links)
{
string link = o as string;
if (link == wbIn.FullName)
wbOut.ChangeLink(link, wbOut.FullName, Excel.XlLinkType.xlLinkTypeExcelLinks);
}
}
我试图使用建议的方法,但有一个例外:
无法将"System.object[*]"类型的对象强制转换为"System.object[]"类型
在C#4.0中,您将需要首先转换为对象。我的版本对我来说很好:
private static void BreakAllExternalLinks(Excel.Workbook wbFrom, Excel.Workbook wbTo)
{
Array links = (Array)((object)wbTo.LinkSources(Excel.XlLink.xlExcelLinks));
if (links != null)
{
foreach (object o in links)
{
string link = o as string;
if (link == wbFrom.FullName)
{
wbTo.ChangeLink(link, wbTo.FullName, Excel.XlLinkType.xlLinkTypeExcelLinks);
}
}
}
}