繁体   English   中英

使用 EPPlus 复制/克隆 Excel 图表

[英]Copy/Clone an Excel Chart with EPPlus

我在我的项目中使用 EPPlus,我知道您可以复制现有的形状,但是没有复制现有图表的方法。

我已经设置了一个带有模板图表的工作簿,我需要复制和更新系列以指向不同的数据表/集。

我可以毫无顾虑地填充数据并可以创建新图表,但随后需要调整大小、位置和样式。 克隆图表模板并修改系列和位置以简化代码会容易得多。

目前我使用这种方法:

// wb is an ExcelWorkbook
ExcelWorksheet ws = wb.Worksheets[sheetIdx];
ExcelChart chart = (ExcelChart)ws.Drawings[0];
ExcelChart cc = ws.Drawings.AddChart("Chart " + (i + 2), eChartType.ColumnClustered);

// invoke methods that will position and size new chart

// copy starting chart xml so will have identical styling, series, legend etc
var xml = XDocument.Parse(chart.ChartXml.InnerXml);
XNamespace nsC = "http://schemas.openxmlformats.org/drawingml/2006/chart";
XNamespace nsA = "http://schemas.openxmlformats.org/drawingml/2006/main";

// modify xml to update Category, Title and Values formulas
var fs = xml.Descendants(nsC + "f");
foreach (var f in fs)
{
    f.Value = ws.Cells[f.Value].Offset(chartNumRows + 1, 0).FullAddressAbsolute;
}

// set new chart xml to modified xml.
cc.ChartXml.InnerXml = xml.ToString();

哪个有效,但有几个缺点。

1)克隆的chart.series(在我的例子中是cc)还没有设置,偷看代码这是因为它只在对象构造过程中完成。 如果我可以更新此属性,那么我将能够轻松解决第二个问题

2)我需要删除所有系列并添加新系列,因为系列属性没有正确初始化,这比应该的更难。

任何帮助在图表中初始化属性或克隆原件的更好方法将不胜感激!

似乎没有内置功能,我可以想出的其他重新加载方法需要对 EPPlus 源进行太多更改,因此在找到更好的解决方案之前,我已将以下方法添加到 EPPlus\\Drawings\\ExcelDrawings 。CS

public ExcelChart CloneChart(ExcelChart SourceChart, String NewName)
{
    // Create clone
    var tempClone = this.AddChart(NewName, SourceChart.ChartType, null);
    tempClone.ChartXml.InnerXml = SourceChart.ChartXml.InnerXml;

    // Reload clone
    using (tempClone.Part.Stream = new MemoryStream())
    {
        // Create chart object using temps package and xml
        var chartXmlBytes = Encoding.ASCII.GetBytes(tempClone.ChartXml.OuterXml);
        tempClone.Part.Stream.Write(chartXmlBytes, 0, chartXmlBytes.Length);
        var finalClone = ExcelChart.GetChart(this, tempClone.TopNode);

        // Remove old from collection
        var index = _drawingNames[tempClone.Name];
        var draw = _drawings[index];
        for (int i = index + 1; i < _drawings.Count; i++)
            _drawingNames[_drawings[i].Name]--;
        _drawingNames.Remove(draw.Name);
        _drawings.Remove(draw);

        // Add new to collection
        finalClone.Name = tempClone.Name;
        _drawings.Add(finalClone);
        _drawingNames.Add(finalClone.Name, _drawings.Count - 1);

        // Done
        return finalClone;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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