Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用ePlus复制/克隆Excel图表_C#_Epplus - Fatal编程技术网

C# 使用ePlus复制/克隆Excel图表

C# 使用ePlus复制/克隆Excel图表,c#,epplus,C#,Epplus,我在我的项目中使用EPPlus,我知道您可以复制现有形状,但是没有复制现有图表的方法 我已经设置了一个带有模板图表的工作簿,我需要复制和更新该系列以指向不同的datatable/集 我可以毫无顾虑地填充数据,并可以创建新图表,但随后需要调整大小、位置和样式。克隆图表模板并修改序列和位置以简化代码会容易得多 目前我使用这种方法: // wb is an ExcelWorkbook ExcelWorksheet ws = wb.Worksheets[sheetIdx]; ExcelChart cha

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

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

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

目前我使用这种方法:

// 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;
    }
}
public ExcelChart CloneChart(ExcelChart SourceChart,String NewName)
{
//创建克隆
var tempClone=this.AddChart(NewName,SourceChart.ChartType,null);
tempClone.ChartXml.InnerXml=SourceChart.ChartXml.InnerXml;
//重新加载克隆
使用(tempClone.Part.Stream=new MemoryStream())
{
//使用temps包和xml创建图表对象
var chartXmlBytes=Encoding.ASCII.GetBytes(tempClone.ChartXml.OuterXml);
tempClone.Part.Stream.Write(chartXmlBytes,0,chartXmlBytes.Length);
var finalClone=ExcelChart.GetChart(这是tempClone.TopNode);
//从收藏中删除旧的
变量索引=_drawingNames[tempClone.Name];
var draw=_Draws[索引];
对于(int i=索引+1;i<\u draws.Count;i++)
_图纸名称[_图纸[i].Name]--;
_drawingNames.Remove(draw.Name);
_图纸。移除(绘制);
//向集合中添加新内容
finalClone.Name=tempClone.Name;
_图纸。添加(最终克隆);
_drawingNames.Add(finalClone.Name,_drawings.Count-1);
//完成
返回最终克隆;
}
}