[Office 2010 開發 ] 如何使用 OpenXML 把 Excel 中的圖表匯到 Word 中

  • 11406
  • 0

[Office 2010 開發 ] 如何使用 OpenXML 把 Excel 中的圖表匯到 Word 中

在本文中將會介紹及實作下方幾項動作:

  1. 先建立一個含有「內容控制項」的 Word 文件以當成範本內容
  2. 利用 Open XML SDK 來開啟 Word 及 Excel 以利進行相關操作
  3. 透過「內容控制項」來判別成 Word 文件插入圖表的依據
  4. 然後開啟 Excel 並把 Excel 中的圖表進行複製作業
  5. 給定讓圖表的 ID 及 Name 值
  6. 複製到 Word 的 「內容控制項」 中
  7. 存檔

 

 

 

image

>> 這是來源檔案 ( Excel 檔 ),內含一個圖表

 

 

 

image

>> 然後我們建立一個 Word 樣版檔案,其中 設立一個「內容控制項」以利嵌入 Excel 中的圖表

 

 

 

image

>> 這就最後嵌入完成之後的 Word 檔案。

 

 

 

 

 

☆ 程式部份

 

◇ 請先建立一個 Concole Application (主控台)

◇ 再把 Program.cs 檔更改成如下的程式碼

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.IO;
   6:  using DocumentFormat.OpenXml.Packaging;
   7:  using DocumentFormat.OpenXml.Wordprocessing;
   8:  using d = DocumentFormat.OpenXml.Drawing;
   9:  using DocumentFormat.OpenXml.Drawing.Charts;
  10:  using wp = DocumentFormat.OpenXml.Drawing.Wordprocessing;
  11:  using DocumentFormat.OpenXml.Drawing.Spreadsheet;
  12:   
  13:   
  14:  namespace ImportChartFromExcelToWord
  15:  {
  16:      class Program
  17:      {
  18:          static void Main(string[] args)
  19:          {
  20:              //設定變數:
  21:              //檔案匯出(output.docx) 及 來源檔案(chart.xlsx) 和樣版檔案(template.docx)
  22:              string outputDoc = "output.docx";
  23:              File.Copy("template.docx", outputDoc, true);
  24:              ImportChartFromSpreadsheet("chart.xlsx", outputDoc);
  25:          }
  26:   
  27:          static void ImportChartFromSpreadsheet(string spreadsheetFileName, string wordFileName)
  28:          {
  29:              //開啟 Word 檔案
  30:              using (WordprocessingDocument myWordDoc = WordprocessingDocument.Open(wordFileName, true))
  31:              {
  32:                  //尋找內容控制項以放入圖表
  33:                  MainDocumentPart mainPart = myWordDoc.MainDocumentPart;
  34:                  SdtBlock sdt = mainPart.Document.Descendants<SdtBlock>().Where(
  35:                           s => s.SdtProperties.GetFirstChild<Alias>().Val.Value.Equals("Chart1")).First();
  36:                  
  37:                  Paragraph p = sdt.SdtContentBlock.GetFirstChild<Paragraph>();
  38:                  p.RemoveAllChildren();
  39:   
  40:                  //建立一個新的嵌入圖像物件執行個體
  41:                  Run r = new Run();
  42:                  p.Append(r);
  43:                  Drawing drawing = new Drawing();
  44:                  r.Append(drawing);
  45:   
  46:                  //透過樣版文件檔案以利嵌入作業
  47:                  wp.Inline inline = new wp.Inline(
  48:                                          new wp.Extent() 
  49:                                              { Cx = 5486400, Cy = 3200400 });
  50:   
  51:                  //開啟 Excel 檔案
  52:                  using (SpreadsheetDocument mySpreadsheet = SpreadsheetDocument.Open(spreadsheetFileName, true))
  53:                  {
  54:                      //取得所適切的內容
  55:                      WorkbookPart workbookPart = mySpreadsheet.WorkbookPart;
  56:                      WorksheetPart worksheetPart = (WorksheetPart)workbookPart.GetPartById("rId1");
  57:                      DrawingsPart drawingPart = worksheetPart.DrawingsPart;
  58:                      ChartPart chartPart = (ChartPart)drawingPart.GetPartById("rId1");
  59:   
  60:                      //複製圖表並新增至 Word 檔案中
  61:                      ChartPart importedChartPart = mainPart.AddPart<ChartPart>(chartPart);
  62:                      string relId = mainPart.GetIdOfPart(importedChartPart);
  63:   
  64:                      //該架構項目中包含圖表的相關資訊
  65:                      GraphicFrame frame = drawingPart.WorksheetDrawing.Descendants<GraphicFrame>().First();
  66:                      string chartName = frame.NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Name;
  67:   
  68:                      //複製該截點以新增至 Word 檔案裡
  69:                      d.Graphic clonedGraphic = (d.Graphic)frame.Graphic.CloneNode(true);
  70:                      ChartReference c = clonedGraphic.GraphicData.GetFirstChild<ChartReference>();
  71:                      c.Id = relId;
  72:   
  73:                      //給定圖表一個唯一的 ID 及名稱
  74:                      wp.DocProperties docPr = new wp.DocProperties();
  75:                      docPr.Name = chartName;
  76:                      docPr.Id = GetMaxDocPrId(mainPart) + 1;
  77:   
  78:                      //新增圖表資料到內嵌的圖形物像中
  79:                      inline.Append(docPr, clonedGraphic);
  80:                      drawing.Append(inline);
  81:                  }
  82:                  mainPart.Document.Save();
  83:              }
  84:          }
  85:   
  86:          static uint GetMaxDocPrId(MainDocumentPart mainPart)
  87:          {
  88:              uint max = 1;
  89:   
  90:              //取得 docPr 變數項目中之最大 ID 值
  91:              foreach (wp.DocProperties docPr in mainPart.Document.Descendants<wp.DocProperties>())
  92:              {
  93:                  uint id = docPr.Id;
  94:                  if (id > max)
  95:                      max = id;
  96:              }
  97:              return max; 
  98:          }
  99:      }
 100:  }

 

 

 

 

>> 檔案下載:點我下載

 

 

 

 

 

 

>> 參考翻譯及引用:Importing Charts from Spreadsheets to Wordprocessing Documents