excelchartsms-wordopenxmlopenxml-sdk

How to copy a Chart from Excel to Word with OpenXml SDK?


I have an Excel file with one sheet and one chart. I am trying to copy this chart and paste it on a new Word document using OpenXml SDK. I do not want an image of the chart, but an editable chart object, not referenced to the Excel file.

This is what I tried:

using (SpreadsheetDocument document = SpreadsheetDocument.Open("Test1.xlsx", true))
{
     var bkPart = document.WorkbookPart;
     var workbook = bkPart.Workbook;
     var s = workbook.Sheets.FirstOrDefault();
     var wsPart = bkPart.WorksheetParts.FirstOrDefault();
     var dp = wsPart.DrawingsPart;
     var dWs = dp.WorksheetDrawing;
     var cp = dp.ChartParts.FirstOrDefault();
     var plotArea = cp.ChartSpace.Descendants<PlotArea>().FirstOrDefault();

     using (var docx = WordprocessingDocument.Open("Test1.docx", true))
     {
          docx.MainDocumentPart.Document.Body.RemoveAllChildren();
          var cpw = docx.MainDocumentPart.AddPart(cp);
          var p = new DocumentFormat.OpenXml.Wordprocessing.Paragraph();
          var r = new Run();
          var d = new Drawing();
          var i = new Inline();
          var g = new Graphic();
          var gd = new GraphicData();
          var c = new DocumentFormat.OpenXml.Drawing.Charts.Chart();

          docx.MainDocumentPart.Document.Body.Append(p);
          p.Append(r);
          r.Append(d);
          d.Append(i);
          i.Append(g);
          g.Append(gd);
          gd.Append(c);
          // I am stuck here
     }
}

I tried to take the ChartPart from Excel and adding it to the Word document and then to create a new chart referencing the inserted new ChartPart. Unfortunately, I am stuck on this step. How can I get and use this reference to create the chart? Otherwise is there another way to copy a chart from Excel to Word?

Thanks in advance.


Solution

  • I found this workaround to copy a chart from Excel to Word:

    1. Create a new ChartPart on the Word document.
    2. Add to this ChartPart a ChartSpace cloned from Excel.
    3. Add a new chart to the Word document referencing the new ChartPart.

    This is the code:

    using (SpreadsheetDocument document = SpreadsheetDocument.Open("Test1.xlsx", true))
    {
        var bkPart = document.WorkbookPart;
        var workbook = bkPart.Workbook;
        var s = workbook.Sheets.FirstOrDefault();
        var wsPart = bkPart.WorksheetParts.FirstOrDefault();
        var dp = wsPart.DrawingsPart;
        var dWs = dp.WorksheetDrawing;
        var cp = dp.ChartParts.FirstOrDefault();
        using (var docx = WordprocessingDocument.Open("Test1.docx", true))
        {
            MainDocumentPart mainPart = docx.MainDocumentPart;
            ChartPart chartPart = mainPart.AddNewPart<ChartPart>("rId777");
            chartPart.ChartSpace = (ChartSpace)cp.ChartSpace.Clone();
    
            var paragraph = new DocumentFormat.OpenXml.Wordprocessing.Paragraph() { RsidParagraphAddition = "00C75AEB", RsidRunAdditionDefault = "000F3EFF" };
            Run run = new Run();
            Drawing drawing = new Drawing();
            Inline inline = new Inline();
            inline.Append(new Extent() { Cx = 5274310L, Cy = 3076575L });
            DocProperties docPros = new DocProperties() { Id = (UInt32Value)1U, Name = "Chart7" };
            inline.Append(docPros);
            Graphic g = new Graphic();
            var graphicData = new GraphicData() { Uri = "http://schemas.openxmlformats.org/drawingml/2006/chart" };
            var chartReference = new ChartReference() { Id = "rId777" };
            graphicData.Append(chartReference);
            g.Append(graphicData);
            inline.Append(g);
            drawing.Append(inline);
            run.Append(drawing);
            paragraph.Append(run);
            mainPart.Document.Body.Append(paragraph);
        }
    }