我最终解决了这个问题!
步骤:
Generate xlsx file with my data in it.
Save the xlsx file locally
In my word document create a new chart part and generate the graph contents
ChartPart wordChartPart = document.MainDocumentPart.AddNewPart<ChartPart>();
string wordChartId = document.MainDocumentPart.GetIdOfPart(wordChartPart);
WordDocumentBuilder.Workflows.SpreadsheetUtils.GenerateBarChartPart(wordChartPart, categories, dataRows);
Embed the spreadsheet in the ChartPart
EmbeddedPackagePart embeddedObjectPart = wordChartPart.AddEmbeddedPackagePart(@"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
using (FileStream stream = new FileStream(file, FileMode.Open))
{
byte[] documentBytes = new byte[stream.Length];
stream.Read(documentBytes, 0, documentBytes.Length);
using (BinaryWriter writer = new BinaryWriter(embeddedObjectPart.GetStream()))
{
writer.Write(documentBytes);
writer.Flush();
}
}
I could then insert an Inline Drawing into my word document which referenced the chart part.
GenerateBarChartPart
中做了什么,以及这对于步骤4是必要的吗?此外,步骤5是否必要才能在生成的文档中看到图表?(如果这些对于有OpenXML经验的人来说很明显,那我很抱歉。我刚开始使用DocumentFormat.OpenXML,正在进行一些原型设计,以查看我们团队是否可以合理地替换我们使用的EPPlus和Xceed DocX。) - William您可以同时打开新的Word文档和包含图表的Excel表格。 您可以在Word文档中添加一些富文本内容控件,并将Excel表格的图表部分插入到这些位置。 请确保您的图表有标题。您可以通过标题来读取图表。 要将它们附加到Word文档中,您需要创建一个段落对象并将其附加到运行对象中,还需要定义一个内联对象以附加图表。 希望您能通过查看以下示例来理解我所说的事情。
private string WordReportGeneration(string docPath, string excelPath)
{
string[] chartTitles = new string[] {"","","","","","",.... };//Chart titles
string[] bookMark = new string[] { "C1", "C2", "C3",..... };//rich text controls of the word doc
for (int i = 0; i < chartTitles.Length; i++) //going through the chart title array
{
using (WordprocessingDocument myWordDoc = WordprocessingDocument.Open(docPath, true))
{
MainDocumentPart mainPart = myWordDoc.MainDocumentPart;
SdtBlock sdt = null;
mainPart.Document.Descendants<SdtBlock>().ToList().ForEach(b => {
var child = b.SdtProperties.GetFirstChild<Tag>();
if (child != null && child.Val.Equals(bookMark[i]))
sdt = b;
});
Paragraph p = sdt.SdtContentBlock.GetFirstChild<Paragraph>();
p.RemoveAllChildren();
Run r = new Run();
p.Append(r);
Drawing drawing = new Drawing();
r.Append(drawing);
Inline inline = new Inline(
new Extent()
{ Cx = 5486400, Cy = 3200400 });
using (SpreadsheetDocument mySpreadsheet = SpreadsheetDocument.Open(excelPath, true))
{
WorkbookPart workbookPart = mySpreadsheet.WorkbookPart;
Sheet theSheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == "Report");
WorksheetPart worksheetPart = (WorksheetPart)workbookPart.GetPartById(theSheet.Id);
DrawingsPart drawingPart = worksheetPart.DrawingsPart;
ChartPart chartPart = (ChartPart)drawingPart.ChartParts.FirstOrDefault(x =>
x.ChartSpace.ChildElements[4].FirstChild.InnerText.Trim() == chartTitles[i]);
ChartPart importedChartPart = mainPart.AddPart<ChartPart>(chartPart);
string relId = mainPart.GetIdOfPart(importedChartPart);
DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame frame = drawingPart.WorksheetDrawing.Descendants<DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame>().First();
Graphic clonedGraphic = (Graphic)frame.Graphic.CloneNode(true);
ChartReference c = clonedGraphic.GraphicData.GetFirstChild<ChartReference>();
c.Id = relId;
DocProperties docPr = new DocProperties();
docPr.Name = "XXX";
docPr.Id = GetMaxDocPrId(mainPart) + 1;
inline.Append(docPr, clonedGraphic);
drawing.Append(inline);
}
myWordDoc.Save();
myWordDoc.Close();
}
}
return docPath;
}
输入代码在这里
enter code here