c#合并单元格作为标头地址epplus

c#合并单元格作为标头地址epplus,c#,epplus,C#,Epplus,如何在ePlus中将HeaderAddress设置为群集条形图的两个单元格?我的数据库输出中有以下数据,其中第一列是您可以看到的合并单元格 我正在寻找以下数据布局 请注意,图像来自数据的副本,但在Excel中生成 到目前为止,我所尝试的基本上是 ExcelChartSerie s = chart.Series.Add(axis.Address, xAxis.Address); s.HeaderAddress = new ExcelAddress(startRow + r, GetColumnN

如何在ePlus中将HeaderAddress设置为群集条形图的两个单元格?我的数据库输出中有以下数据,其中第一列是您可以看到的合并单元格

我正在寻找以下数据布局

请注意,图像来自数据的副本,但在Excel中生成

到目前为止,我所尝试的基本上是

ExcelChartSerie s = chart.Series.Add(axis.Address, xAxis.Address);
s.HeaderAddress = new ExcelAddress(startRow + r, GetColumnNumberByName(startColumn), startRow + 1, GetColumnNumberByName(startColumn) + 1);

其中,我或多或少地选择了当前行和两列。这给了我“地址必须是行、列或单个单元格”,但为了使其正常工作,我必须选择多个单元格,否?

Epplus无法设置它。这并不难,但需要XML操作。有点难看,但它完成了任务。由于不了解您的代码,我编写了一个快速的单元测试来演示。它必须与正确的图表类型相匹配,因此如果它不是
BarClustered
请告诉我:

[TestMethod]
公共无效图表\u Meged\u页眉\u测试()
{
//加入一些数据
var数据表=新数据表(“tblData”);
datatable.Columns.AddRange(新[]
{
新数据列(“Col1”,typeof(string)),
新数据列(“Col2”,类型(int))
});
对于(变量i=0;i<10;i++)
{
var row=datatable.NewRow();
第[0]行=$“项{(i%2==0?”A:“B”)}”;
行[1]=i*10;
datatable.Rows.Add(行);
}
//创建一个测试文件
var fileInfo=newfileinfo(@“c:\temp\Chart\u Meged\u Header\u Test.xlsx”);
如果(fileInfo.Exists)
fileInfo.Delete();
使用(var pck=new ExcelPackage(fileInfo))
{
var工作簿=pck.工作簿;
var工作表=工作簿。工作表。添加(“表1”);
工作表.单元格[“B1”].LoadFromDataTable(datatable,true);
工作表.Column(4).Style.Numberformat.Format=“m/d/yyyy”;
var图表=工作表.Drawings.AddChart(“图表测试”,eChartType.bar);
var serie=chart.Series.Add(工作表.单元格[“C2:C11”]、工作表.单元格[“B2:B11”]);
图表设置位置(0,0,3,0);
图表.设置尺寸(120);
//添加合并的标题
工作表。单元格[“A2”]。Value=“第1组”;
工作表。单元格[“A2:A6”]。合并=真;
工作表.单元格[“A7”].Value=“第2组”;
工作表。单元格[“A7:A11”]。合并=真;
//获取对工作表xml的引用以获得适当的命名空间
var chartXml=chart.chartXml;
var nsm=新的XmlNamespaceManager(chartXml.NameTable);
var nsuri=chartXml.DocumentElement.NamespaceURI;
nsm.AddNamespace(“c”,nsuri);
//获取系列ref及其cat
var serNode=chartXml。选择SingleNode(“c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser”,nsm);
var catNode=serNode。选择singlenode(“c:cat”,nsm);
//获取Y轴参考以替换为多级节点
var numRefNode=catNode.SelectSingleNode(“c:numRef”,nsm);
var multilvlstrefnode=chartXml.CreateNode(XmlNodeType.Element,“c:multilvlstref”,nsuri);
//设置正确的单元格引用并替换节点
var fNode=chartXml.CreateElement(“c:f”,nsuri);
fNode.InnerXml=numRefNode.SelectSingleNode(“c:f”,nsm).InnerXml;
fNode.InnerXml=fNode.InnerXml.Replace(“$B$2”,“$A$2”);
multilvlstrefnode.AppendChild(fNode);
ReplaceChild(multilvlstrefnode,numRefNode);
//设置多级标志
var noMultiLvlLblNode=chartXml.CreateElement(“c:noMultiLvlLbl”,nsuri);
var att=chartXml.CreateAttribute(“val”);
附件值=“0”;
noMultiLvlLblNode.Attributes.Append(att);
var catAxNode=chartXml。选择SingleNode(“c:chartSpace/c:chart/c:plotArea/c:catAx”,nsm);
AppendChild(noMultiLvlLblNode);
pck.Save();
}
}
将其作为输出:


谢谢。我将对此进行测试并查看。一旦我理解了所有内容,我会将其标记为已完成,并使其工作一次。您知道如何调试损坏的excel的任何工具吗?我试过了,您的代码在处理新图表时效果很好,但当我尝试将此应用于现有图表时,它会中断,excel会删除中断的图表,但我找不到问题所在。我尝试了SDK工具,但它进行了验证,所以我不知道该去哪里start@Pochen我不会对此感到惊讶。我敢打赌,因为它实际上是由Excel(而不是EPPlus)保存的,所以Excel添加了我们在上面创建的一些或所有新的XML属性。因此,只要有
CreateElement
CreateAttribute
就必须检查它是否已经存在。如果是,则必须对其进行更新,而不是为其创建一个全新的条目。如果你想不出来,把你的文件贴到某个地方,我们可以看看。这就是现在的结果;没有撞车,几乎被挖了出来。我发现noMultiLvlLbl是重复的,所以这是用来防止它重复的新代码@波钦哼……没有什么东西能让我大吃一惊。也许要确保缓存被清理干净。使用7zip打开xlsx,并检查之前和之后的chart1.xml文件。如果你被卡住了,把文件贴到某个地方。