スプレッドシート ドキュメントにグラフを挿入する
適用対象: Excel 2010 | Office 2010 | PowerPoint 2010 | Word 2010
この記事の内容
SpreadsheetDocument オブジェクトを取得する
SpreadsheetML ドキュメントの基本構造
行要素
セル要素
セル値要素
サンプル コードの動作のしくみ
サンプル コード
このトピックでは、Open XML SDK 2.0 for Microsoft Office のクラスを使用して、プログラムによってスプレッドシート ドキュメントにグラフを挿入する方法を説明します。
このトピックのコードをコンパイルするには、次のアセンブリ ディレクティブが必要です。
using System.Collections.Generic;
using System.Linq;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Drawing;
using DocumentFormat.OpenXml.Drawing.Charts;
using DocumentFormat.OpenXml.Drawing.Spreadsheet;
Imports System.Collections.Generic
Imports System.Linq
Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet
Imports DocumentFormat.OpenXml.Drawing
Imports DocumentFormat.OpenXml.Drawing.Charts
Imports DocumentFormat.OpenXml.Drawing.Spreadsheet
SpreadsheetDocument オブジェクトを取得する
Open XML SDK では、SpreadsheetDocument クラスが Excel ドキュメント パッケージを表します。Excel ドキュメントを開いて操作するには、ドキュメントから SpreadsheetDocument クラスのインスタンスを作成します。ドキュメントからインスタンスを作成した後、ワークシートが入っているメインのブック パーツにアクセスできます。パッケージ内では、SpreadsheetML マークアップを使用してドキュメントのコンテンツを XML で表現します。
ドキュメントからクラス インスタンスを作成するには、Open() のいずれかのメソッドを呼び出します。メソッドにはいくつかの種類があり、それぞれシグネチャが異なります。このトピックのサンプル コードでは、2 つのパラメーターを必要とするシグネチャを持つ Open(String, Boolean) メソッドを使用します。最初のパラメーターには、開くドキュメントを表す完全なパスの文字列を指定します。2 番目のパラメーターは true または false で、開いたファイルを編集するかどうかを指定します。このパラメーターを false に指定した場合は、ドキュメントに対する変更が保存されません。
Open メソッドを呼び出すコードは、次の using ステートメント内に記述します。
// Open the document for editing.
using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true))
{
// Insert other code here.
}
' Open the document for editing.
Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True)
' Insert other code here.
End Using
using ステートメントは、典型的な .Open, .Save, .Close シーケンスの代わりに使える推奨手段です。これを使用すると、対応する右かっこに達したとき、Dispose メソッド (Open XML SDK でリソースのクリーンアップに使われる内部メソッド) が自動的に呼び出されます。using ステートメントに続くブロックが、using ステートメントで作成または指定したオブジェクト (このケースでは document) のスコープとして設定されます。
SpreadsheetML ドキュメントの基本構造
SpreadsheetML ドキュメントの基本構造は、<sheets> 要素と <sheet> 要素で構成されます。これらの要素は、Workbook 内のワークシートを参照します。Worksheet ごとに個別の XML ファイルが作成されます。たとえば、MySheet1、MySheet2、Chart1 という名前の 3 つのワークシートがあるブックの SpreadsheetML は Workbook.xml ファイル内にあり、次のコード例のように記述されます。
<x:workbook xmlns:r="https://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:x="https://schemas.openxmlformats.org/spreadsheetml/2006/main">
<x:fileVersion appName="xl" lastEdited="5" lowestEdited="4" rupBuild="9302" />
<x:workbookPr filterPrivacy="1" defaultThemeVersion="124226" />
<x:bookViews>
<x:workbookView xWindow="240" yWindow="108" windowWidth="14808" windowHeight="8016" activeTab="1" />
</x:bookViews>
<x:sheets>
<x:sheet name="MySheet1" sheetId="1" r:id="rId1" />
<x:sheet name="MySheet2" sheetId="2" r:id="rId2" />
<x:sheet name="Chart1" sheetId="3" type="chartsheet" r:id="rId3"/>
</x:sheets>
<x:calcPr calcId="122211" />
</x:workbook>
ワークシート XML ファイルには、<sheetData> などのブロック レベル要素が 1 つ以上含まれます。この要素はセル テーブルを表し、1 つ以上の行 (<row>) 要素を含みます。行要素には、1 つ以上の セル要素 (<c>) が含まれます。各セル要素には、そのセルの値を表すセル値要素 (<v>) が含まれます。たとえば、あるブックの最初のワークシート (セル A1 の値が 100 で、それ以外の値はないものとする) の SpreadsheetML は、ファイル Sheet1.xml 内に置かれ、次のコード例のように記述されます。
<?xml version="1.0" encoding="UTF-8" ?>
<worksheet xmlns="https://schemas.openxmlformats.org/spreadsheetml/2006/main">
<sheetData>
<row r="1">
<c r="A1">
<v>100</v>
</c>
</row>
</sheetData>
</worksheet>
Open XML SDK 2.0 を使用すると、SpreadsheetML 要素に対応する厳密に型指定されたクラスを使用したドキュメント構造とコンテンツを作成できます。これらのクラスは DocumentFormat.OpenXml.Spreadsheet 名前空間にあります。次の表は、workbook、Sheets、Sheet、worksheet、SheetData の各要素に対応するクラスのクラス名の一覧です。
SpreadsheetML の要素 |
Open XML SDK 2.0 のクラス |
説明 |
---|---|---|
workbook |
DocumentFormat.OpenXml.Spreadsheet.Workbook |
メイン ドキュメント パーツのルート要素。 |
sheets |
DocumentFormat.OpenXml.Spreadsheet.Sheets |
ISO/IEC 29500 (英語) の仕様で規定されている、シート、ファイル バージョン、その他のブロック レベル構造のコンテナー。 |
sheet |
DocumentFormat.OpenXml.Spreadsheet.Sheet |
シート定義ファイルを指し示すシート。 |
worksheet |
DocumentFormat.OpenXml.Spreadsheet.Worksheet |
シート データが含まれているシート定義ファイル。 |
sheetData |
DocumentFormat.OpenXml.Spreadsheet.SheetData |
セルの表。行ごとにグループ化されています。 |
row |
セルの表内の行。 |
|
c |
行内のセル。 |
|
v |
セルの値。 |
行要素
ここでは、行、セル、およびセル値の各要素を使用します。したがって、これらの要素について理解していると役に立ちます。行 (<row>) 要素については、ISO/IEC 29500 (英語) 仕様書の次の文面で導入されています。
行要素は、ワークシートの行全体についての情報を表し、ワークシート内の特定の行に対するすべてのセル定義を含みます。
次の row は、ワークシートの行 2 についての情報を表し、3 つのセル定義を含みます。
<row r="2" spans="2:12">
<c r="C2" s="1">
<f>PMT(B3/12,B4,-B5)</f>
<v>672.68336574300008</v>
</c>
<c r="D2">
<v>180</v>
</c>
<c r="E2">
<v>360</v>
</c>
</row>
c ISO/IEC29500: 2008.
次の XML スキーマ コード例では、行要素のコンテンツが定義されています。
<complexType name="CT_Row">
<sequence>
<element name="c" type="CT_Cell" minOccurs="0" maxOccurs="unbounded"/>
<element name="extLst" minOccurs="0" type="CT_ExtensionList"/>
</sequence>
<attribute name="r" type="xsd:unsignedInt" use="optional"/>
<attribute name="spans" type="ST_CellSpans" use="optional"/>
<attribute name="s" type="xsd:unsignedInt" use="optional" default="0"/>
<attribute name="customFormat" type="xsd:boolean" use="optional" default="false"/>
<attribute name="ht" type="xsd:double" use="optional"/>
<attribute name="hidden" type="xsd:boolean" use="optional" default="false"/>
<attribute name="customHeight" type="xsd:boolean" use="optional" default="false"/>
<attribute name="outlineLevel" type="xsd:unsignedByte" use="optional" default="0"/>
<attribute name="collapsed" type="xsd:boolean" use="optional" default="false"/>
<attribute name="thickTop" type="xsd:boolean" use="optional" default="false"/>
<attribute name="thickBot" type="xsd:boolean" use="optional" default="false"/>
<attribute name="ph" type="xsd:boolean" use="optional" default="false"/>
</complexType>
セル要素
セル (<c>) 要素については、ISO/IEC 29500 (英語) 仕様書の次の文面で導入されています。
このコレクションは、ワークシート内のセルを表します。セルの場所 (参照)、値、データ型、書式設定、および式についての情報がここでは表されます。
次の例では、グリッド内のアドレスが C6、スタイル インデックスが 6、値メタデータ インデックスが 15 であるセルに対して格納される情報を示します。セルには、式だけでなく、その式の計算結果も含まれます。
<c r="C6" s="1" vm="15">
<f>CUBEVALUE("xlextdat9 Adventure Works",C$5,$A6)</f>
<v>2838512.355</v>
</c>
c ISO/IEC29500: 2008.
次の XML スキーマ コード例では、この要素のコンテンツが定義されています。
<complexType name="CT_Cell">
<sequence>
<element name="f" type="CT_CellFormula" minOccurs="0" maxOccurs="1"/>
<element name="v" type="ST_Xstring" minOccurs="0" maxOccurs="1"/>
<element name="is" type="CT_Rst" minOccurs="0" maxOccurs="1"/>
<element name="extLst" minOccurs="0" type="CT_ExtensionList"/>
</sequence>
<attribute name="r" type="ST_CellRef" use="optional"/>
<attribute name="s" type="xsd:unsignedInt" use="optional" default="0"/>
<attribute name="t" type="ST_CellType" use="optional" default="n"/>
<attribute name="cm" type="xsd:unsignedInt" use="optional" default="0"/>
<attribute name="vm" type="xsd:unsignedInt" use="optional" default="0"/>
<attribute name="ph" type="xsd:boolean" use="optional" default="false"/>
</complexType>
セル値要素
セル値 (<c>) 要素については、ISO/IEC 29500 (英語) 仕様書の次の文面で導入されています。
この要素は、セルに含まれる値を表します。セルに文字列が含まれる場合、この値は共有文字列テーブルのインデックスであり、実際の文字列値を指しています。文字列以外の場合は、セルの値はこの要素で直接表されます。式を含むセルは、この要素での式の最終的な計算結果を表します。
共有文字列テーブルを実装するのが好ましくないアプリケーションでは、共有文字列テーブルで文字列を表すのと同じように、(<c> の <v> 要素の代わりに) <c> の <is> 要素で "インライン文字列" を表すことができます。
c ISO/IEC29500: 2008.
次の例では、セル B4 には値 360 が含まれます。
<c r="B4">
<v>360</v>
</c>
サンプル コードの動作のしくみ
スプレッドシート ファイルを読み取り/書き込みアクセス用に開いた後、指定したワークシートが存在するかどうかをコードで検証します。その後、AddNewPart メソッドを使用して新しい DrawingsPart オブジェクトを追加し、それをワークシートの最後に追加して、ワークシート パーツを保存します。その後、新しい ChartPart オブジェクトを追加し、新しい ChartSpace オブジェクトを ChartPart オブジェクトに追加してから、グラフの言語が English-US であることを指定する新しい EditingLanguage オブジェクトを ChartSpace オブジェクトに追加します。
IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>().Where
(s => s.Name == worksheetName);
if (sheets.Count() == 0)
{
// The specified worksheet does not exist.
return;
}
WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id);
// Add a new drawing to the worksheet.
DrawingsPart drawingsPart = worksheetPart.AddNewPart<DrawingsPart>();
worksheetPart.Worksheet.Append(new DocumentFormat.OpenXml.Spreadsheet.Drawing()
{ Id = worksheetPart.GetIdOfPart(drawingsPart) });
worksheetPart.Worksheet.Save();
// Add a new chart and set the chart language to English-US.
ChartPart chartPart = drawingsPart.AddNewPart<ChartPart>();
chartPart.ChartSpace = new ChartSpace();
chartPart.ChartSpace.Append(new EditingLanguage() { Val = new StringValue("en-US") });
DocumentFormat.OpenXml.Drawing.Charts.Chart chart = chartPart.ChartSpace.AppendChild
<DocumentFormat.OpenXml.Drawing.Charts.Chart>
(new DocumentFormat.OpenXml.Drawing.Charts.Chart());
Dim sheets As IEnumerable(Of Sheet) = _
document.WorkbookPart.Workbook.Descendants(Of Sheet)() _
.Where(Function(s) s.Name = worksheetName)
If sheets.Count() = 0 Then
' The specified worksheet does not exist.
Return
End If
Dim worksheetPart As WorksheetPart = _
CType(document.WorkbookPart.GetPartById(sheets.First().Id), WorksheetPart)
' Add a new drawing to the worksheet.
Dim drawingsPart As DrawingsPart = worksheetPart.AddNewPart(Of DrawingsPart)()
worksheetPart.Worksheet.Append(New DocumentFormat.OpenXml.Spreadsheet.Drawing() With {.Id = _
worksheetPart.GetIdOfPart(drawingsPart)})
worksheetPart.Worksheet.Save()
' Add a new chart and set the chart language to English-US.
Dim chartPart As ChartPart = drawingsPart.AddNewPart(Of ChartPart)()
chartPart.ChartSpace = New ChartSpace()
chartPart.ChartSpace.Append(New EditingLanguage() With {.Val = _
New StringValue("en-US")})
Dim chart As DocumentFormat.OpenXml.Drawing.Charts.Chart = _
chartPart.ChartSpace.AppendChild(Of DocumentFormat.OpenXml.Drawing.Charts _
.Chart)(New DocumentFormat.OpenXml.Drawing.Charts.Chart())
BarDirectionValues オブジェクトを Column に設定し、BarGroupingValues オブジェクトを Clustered に設定して、新しい BarChart オブジェクトを作成し、新しい集合横棒グラフを作成します。
その後、Dictionary クラスの各キーを反復処理します。各キーについて、BarChartSeries オブジェクトを BarChart オブジェクトに追加し、BarChartSeries オブジェクトの SeriesText オブジェクトをキーと同じになるように設定します。また、NumberLiteral オブジェクトを BarChartSeries オブジェクトの Values コレクションに追加し、NumberLiteral オブジェクトをキーに対応する Dictionary クラスの値と等しくなるように設定します。
// Create a new clustered column chart.
PlotArea plotArea = chart.AppendChild<PlotArea>(new PlotArea());
Layout layout = plotArea.AppendChild<Layout>(new Layout());
BarChart barChart = plotArea.AppendChild<BarChart>(new BarChart(new BarDirection()
{ Val = new EnumValue<BarDirectionValues>(BarDirectionValues.Column) },
new BarGrouping() { Val = new EnumValue<BarGroupingValues> BarGroupingValues.Clustered) }));
uint i = 0;
// Iterate through each key in the Dictionary collection and add the key to the chart Series
// and add the corresponding value to the chart Values.
foreach (string key in data.Keys)
{
BarChartSeries barChartSeries = barChart.AppendChild<BarChartSeries>
(new BarChartSeries(new Index() { Val = new UInt32Value(i) },
new Order() { Val = new UInt32Value(i) },
new SeriesText(new NumericValue() { Text = key })));
StringLiteral strLit = barChartSeries.AppendChild<CategoryAxisData>
(new CategoryAxisData()).AppendChild<StringLiteral>(new StringLiteral());
strLit.Append(new PointCount() { Val = new UInt32Value(1U) });
strLit.AppendChild<StringPoint>(new StringPoint() { Index = new UInt32Value(0U) })
.Append(new NumericValue(title));
NumberLiteral numLit = barChartSeries.AppendChild<DocumentFormat.
OpenXml.Drawing.Charts.Values>(new DocumentFormat.OpenXml.Drawing.Charts.Values()).AppendChild<NumberLiteral>
(new NumberLiteral());
numLit.Append(new FormatCode("General"));
numLit.Append(new PointCount() { Val = new UInt32Value(1U) });
numLit.AppendChild<NumericPoint>(new NumericPoint() { Index = new UInt32Value(0u)})
.Append(new NumericValue(data[key].ToString()));
i++;
}
' Create a new clustered column chart.
Dim plotArea As PlotArea = chart.AppendChild(Of PlotArea)(New PlotArea())
Dim layout As Layout = plotArea.AppendChild(Of Layout)(New Layout())
Dim barChart As BarChart = plotArea.AppendChild(Of BarChart)(New BarChart _
(New BarDirection() With {.Val = New EnumValue(Of BarDirectionValues) _
(BarDirectionValues.Column)}, New BarGrouping() With {.Val = New EnumValue _
(Of BarGroupingValues)(BarGroupingValues.Clustered)}))
Dim i As UInteger = 0
' Iterate through each key in the Dictionary collection and add the key to the chart Series
' and add the corresponding value to the chart Values.
For Each key As String In data.Keys
Dim barChartSeries As BarChartSeries = barChart.AppendChild(Of BarChartSeries) _
(New BarChartSeries(New Index() With {.Val = New UInt32Value(i)}, New Order() _
With {.Val = New UInt32Value(i)}, New SeriesText(New NumericValue() With {.Text = key})))
Dim strLit As StringLiteral = barChartSeries.AppendChild(Of CategoryAxisData) _
(New CategoryAxisData()).AppendChild(Of StringLiteral)(New StringLiteral())
strLit.Append(New PointCount() With {.Val = New UInt32Value(1UI)})
strLit.AppendChild(Of StringPoint)(New StringPoint() With {.Index = _
New UInt32Value(0UI)}).Append(New NumericValue(title))
Dim numLit As NumberLiteral = barChartSeries.AppendChild _
(Of DocumentFormat.OpenXml.Drawing.Charts.Values)(New DocumentFormat _
.OpenXml.Drawing.Charts.Values()).AppendChild(Of NumberLiteral)(New NumberLiteral())
numLit.Append(New FormatCode("General"))
numLit.Append(New PointCount() With {.Val = New UInt32Value(1UI)})
numLit.AppendChild(Of NumericPoint)(New NumericPoint() With {.Index = _
New UInt32Value(0UI)}).Append(New NumericValue(data(key).ToString()))
i += 1
Next key
次のコードでは、CategoryAxis オブジェクトと ValueAxis オブジェクトをグラフに追加し、Scaling、AxisPosition、TickLabelPosition、CrossingAxis、Crosses、AutoLabeled、LabelAlignment、LabelOffset の各プロパティの値を設定します。また、Legend オブジェクトをグラフに追加し、グラフ パーツを保存します。
barChart.Append(new AxisId() { Val = new UInt32Value(48650112u) });
barChart.Append(new AxisId() { Val = new UInt32Value(48672768u) });
// Add the Category Axis.
CategoryAxis catAx = plotArea.AppendChild<CategoryAxis>(new CategoryAxis(new AxisId()
{ Val = new UInt32Value(48650112u) }, new Scaling(new Orientation()
{
Val = new EnumValue<DocumentFormat.OpenXml.Drawing.Charts.OrientationValues>(
DocumentFormat.OpenXml.Drawing.Charts.OrientationValues.MinMax)
}),
new AxisPosition() { Val = new EnumValue<AxisPositionValues>(AxisPositionValues.Bottom) },
new TickLabelPosition() { Val = new EnumValue<TickLabelPositionValues>(TickLabelPositionValues.NextTo) },
new CrossingAxis() { Val = new UInt32Value(48672768U) },
new Crosses() { Val = new EnumValue<CrossesValues>(CrossesValues.AutoZero) },
new AutoLabeled() { Val = new BooleanValue(true) },
new LabelAlignment() { Val = new EnumValue<LabelAlignmentValues>(LabelAlignmentValues.Center) },
new LabelOffset() { Val = new UInt16Value((ushort)100) }));
// Add the Value Axis.
ValueAxis valAx = plotArea.AppendChild<ValueAxis>(new ValueAxis(new AxisId() { Val = new UInt32Value(48672768u) },
new Scaling(new Orientation()
{
Val = new EnumValue<DocumentFormat.OpenXml.Drawing.Charts.OrientationValues>(
DocumentFormat.OpenXml.Drawing.Charts.OrientationValues.MinMax)
}),
new AxisPosition() { Val = new EnumValue<AxisPositionValues>(AxisPositionValues.Left) },
new MajorGridlines(),
new DocumentFormat.OpenXml.Drawing.Charts.NumberingFormat() { FormatCode = new StringValue("General"),
SourceLinked = new BooleanValue(true) }, new TickLabelPosition() { Val =
new EnumValue<TickLabelPositionValues>(TickLabelPositionValues.NextTo) },
new CrossingAxis() { Val = new UInt32Value(48650112U) }, new Crosses() {
Val = new EnumValue<CrossesValues>(CrossesValues.AutoZero) }, new CrossBetween()
{ Val = new EnumValue<CrossBetweenValues>(CrossBetweenValues.Between) }));
// Add the chart Legend.
Legend legend = chart.AppendChild<Legend>(new Legend(new LegendPosition()
{ Val = new EnumValue<LegendPositionValues>(LegendPositionValues.Right) },
new Layout()));
chart.Append(new PlotVisibleOnly() { Val = new BooleanValue(true) });
// Save the chart part.
chartPart.ChartSpace.Save();
barChart.Append(New AxisId() With {.Val = New UInt32Value(48650112UI)})
barChart.Append(New AxisId() With {.Val = New UInt32Value(48672768UI)})
' Add the Category Axis.
Dim catAx As CategoryAxis = plotArea.AppendChild(Of CategoryAxis) _
(New CategoryAxis(New AxisId() With {.Val = New UInt32Value(48650112UI)}, _
New Scaling(New Orientation() With {.Val = New EnumValue(Of _
DocumentFormat.OpenXml.Drawing.Charts.OrientationValues) _
(DocumentFormat.Open Xml.Drawing.Charts.OrientationValues.MinMax)}), New AxisPosition() With _
{.Val = New EnumValue(Of AxisPositionValues)(AxisPositionValues.Bottom)}, _
New TickLabelPosition() With {.Val = New EnumValue(Of TickLabelPositionValues) _
(TickLabelPositionValues.NextTo)}, New CrossingAxis() With {.Val = New UInt32Value(48672768UI)}, _
New Crosses() With {.Val = New EnumValue(Of CrossesValues)(CrossesValues.AutoZero)} _
, New AutoLabeled() With {.Val = New BooleanValue(True)}, New LabelAlignment()_
With {.Val = New EnumValue(Of LabelAlignmentValues)(LabelAlignmentValues.Center)} _
, New LabelOffset() With {.Val = New UInt16Value(CUShort(100))}))
' Add the Value Axis.
Dim valAx As ValueAxis = plotArea.AppendChild(Of ValueAxis)(New ValueAxis _
(New AxisId() With {.Val = New UInt32Value(48672768UI)}, New Scaling(New _
Orientation() With {.Val = New EnumValue(Of DocumentFormat.OpenXml.Drawing _
.Charts.OrientationValues)(DocumentFormat.OpenXml.Drawing.Charts.OrientationValues.MinMax)}), _
New AxisPosition() With {.Val = New EnumValue(Of AxisPositionValues)(AxisPositionValues.Left)}, _
New MajorGridlines(), New DocumentFormat.OpenXml.Drawing.Charts.NumberingFormat() With {.FormatCode = _
New StringValue("General"), .SourceLinked = New BooleanValue(True)}, New TickLabelPosition() With _
{.Val = New EnumValue(Of TickLabelPositionValues)(TickLabelPositionValues.NextTo)}, New CrossingAxis() _
With {.Val = New UInt32Value(48650112UI)}, New Crosses() With {.Val = New EnumValue(Of CrossesValues) _
(CrossesValues.AutoZero)}, New CrossBetween() With {.Val = New EnumValue(Of CrossBetweenValues) _
(CrossBetweenValues.Between)}))
' Add the chart Legend.
Dim legend As Legend = chart.AppendChild(Of Legend)(New Legend(New LegendPosition() _
With {.Val = New EnumValue(Of LegendPositionValues)(LegendPositionValues.Right)}, New Layout()))
chart.Append(New PlotVisibleOnly() With {.Val = New BooleanValue(True)})
' Save the chart part.
chartPart.ChartSpace.Save()
次のコードは、WorksheetDrawing オブジェクトを作成し、TwoCellAnchor オブジェクトを追加することで、グラフをワークシートに配置します。TwoCellAnchor オブジェクトは、FromMarker アンカーと ToMarker アンカーの間で行と列を移動する場合に、グラフを移動またはサイズ変更する方法を指定します。その後、GraphicFrame オブジェクトを作成してグラフを組み込み、グラフの名前を "Chart 1" に設定して、ワークシートの描画を保存します。
// Position the chart on the worksheet using a TwoCellAnchor object.
drawingsPart.WorksheetDrawing = new WorksheetDrawing();
TwoCellAnchor twoCellAnchor = drawingsPart.WorksheetDrawing.AppendChild<TwoCellAnchor>(new TwoCellAnchor());
twoCellAnchor.Append(new DocumentFormat.OpenXml.Drawing.Spreadsheet.FromMarker(new ColumnId("9"),
new ColumnOffset("581025"),
new RowId("17"),
new RowOffset("114300")));
twoCellAnchor.Append(new DocumentFormat.OpenXml.Drawing.Spreadsheet.ToMarker(new ColumnId("17"),
new ColumnOffset("276225"),
new RowId("32"),
new RowOffset("0")));
// Append a GraphicFrame to the TwoCellAnchor object.
DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame graphicFrame =
twoCellAnchor.AppendChild<DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame>(
new DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame());
graphicFrame.Macro = "";
graphicFrame.Append(new DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualGraphicFrameProperties(
new DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualDrawingProperties() { Id = new UInt32Value(2u),
Name = "Chart 1" }, new DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualGraphicFrameDrawingProperties()));
graphicFrame.Append(new Transform(new Offset() { X = 0L, Y = 0L },
new Extents() { Cx = 0L, Cy = 0L }));
graphicFrame.Append(new Graphic(new GraphicData(new ChartReference() { Id = drawingsPart.GetIdOfPart(chartPart)})
{ Uri = "https://schemas.openxmlformats.org/drawingml/2006/chart" }));
twoCellAnchor.Append(new ClientData());
// Save the WorksheetDrawing object.
drawingsPart.WorksheetDrawing.Save();
' Position the chart on the worksheet using a TwoCellAnchor object.
drawingsPart.WorksheetDrawing = New WorksheetDrawing()
Dim twoCellAnchor As TwoCellAnchor = drawingsPart.WorksheetDrawing.AppendChild(Of _
TwoCellAnchor)(New TwoCellAnchor())
twoCellAnchor.Append(New DocumentFormat.OpenXml.Drawing.Spreadsheet.FromMarker(New _
ColumnId("9"), New ColumnOffset("581025"), New RowId("17"), New RowOffset("114300")))
twoCellAnchor.Append(New DocumentFormat.OpenXml.Drawing.Spreadsheet.ToMarker(New _
ColumnId("17"), New ColumnOffset("276225"), New RowId("32"), New RowOffset("0")))
' Append a GraphicFrame to the TwoCellAnchor object.
Dim graphicFrame As DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame = _
twoCellAnchor.AppendChild(Of DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame) _
(New DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame())
graphicFrame.Macro = ""
graphicFrame.Append(New DocumentFormat.OpenXml.Drawing.Spreadsheet _
.NonVisualGraphicFrameProperties(New DocumentFormat.OpenXml.Drawing.Spreadsheet. _
NonVisualDrawingProperties() With {.Id = New UInt32Value(2UI), .Name = "Chart 1"}, _
New DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualGraphicFrameDrawingProperties()))
graphicFrame.Append(New Transform(New Offset() With {.X = 0L, .Y = 0L}, _
New Extents() With {.Cx = 0L, .Cy = 0L}))
graphicFrame.Append(New Graphic(New GraphicData(New ChartReference() With _
{.Id = drawingsPart.GetIdOfPart(chartPart)}) With {.Uri = _
"https://schemas.openxmlformats.org/drawingml/2006/chart"}))
twoCellAnchor.Append(New ClientData())
' Save the WorksheetDrawing object.
drawingsPart.WorksheetDrawing.Save()
サンプル コード
次のコードでは、Dictionary<TKey, TValue> クラスからのデータを使用する集合横棒グラフを SpreadsheetDocument ドキュメント パッケージに追加します。たとえば、このコード セグメントを使用して、InsertChartInSpreadsheet メソッドを呼び出すことができます。
string docName = @"C:\Users\Public\Documents\Sheet6.xlsx";
string worksheetName = "Joe";
string title = "New Chart";
Dictionary<string,int> data = new Dictionary<string,int>();
data.Add("abc", 1);
InsertChartInSpreadsheet(docName, worksheetName, title, data);
Dim docName As String = "C:\Users\Public\Documents\Sheet6.xlsx"
Dim worksheetName As String = "Joe"
Dim title As String = "New Chart"
Dim data As New Dictionary(Of String, Integer)()
data.Add("abc", 1)
InsertChartInSpreadsheet(docName, worksheetName, title, data)
プログラムを実行した後、"Sheet6.xlsx" という名前のファイルを表示して、挿入されたグラフを確認します。
注意
このコードを実行できるのは 1 回だけです。グラフの複数のインスタンスを作成することはできません。
以下に、C# と Visual Basic による完全なサンプル コードを示します。
// Given a document name, a worksheet name, a chart title, and a Dictionary collection of text keys
// and corresponding integer data, creates a column chart with the text as the series and the integers as the values.
private static void InsertChartInSpreadsheet(string docName, string worksheetName, string title,
Dictionary<string, int> data)
{
// Open the document for editing.
using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true))
{
IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>().
Where(s => s.Name == worksheetName);
if (sheets.Count() == 0)
{
// The specified worksheet does not exist.
return;
}
WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id);
// Add a new drawing to the worksheet.
DrawingsPart drawingsPart = worksheetPart.AddNewPart<DrawingsPart>();
worksheetPart.Worksheet.Append(new DocumentFormat.OpenXml.Spreadsheet.Drawing()
{ Id = worksheetPart.GetIdOfPart(drawingsPart) });
worksheetPart.Worksheet.Save();
// Add a new chart and set the chart language to English-US.
ChartPart chartPart = drawingsPart.AddNewPart<ChartPart>();
chartPart.ChartSpace = new ChartSpace();
chartPart.ChartSpace.Append(new EditingLanguage() { Val = new StringValue("en-US") });
DocumentFormat.OpenXml.Drawing.Charts.Chart chart = chartPart.ChartSpace.AppendChild<DocumentFormat.OpenXml.Drawing.Charts.Chart>(
new DocumentFormat.OpenXml.Drawing.Charts.Chart());
// Create a new clustered column chart.
PlotArea plotArea = chart.AppendChild<PlotArea>(new PlotArea());
Layout layout = plotArea.AppendChild<Layout>(new Layout());
BarChart barChart = plotArea.AppendChild<BarChart>(new BarChart(new BarDirection()
{ Val = new EnumValue<BarDirectionValues>(BarDirectionValues.Column) },
new BarGrouping() { Val = new EnumValue<BarGroupingValues>(BarGroupingValues.Clustered) }));
uint i = 0;
// Iterate through each key in the Dictionary collection and add the key to the chart Series
// and add the corresponding value to the chart Values.
foreach (string key in data.Keys)
{
BarChartSeries barChartSeries = barChart.AppendChild<BarChartSeries>(new BarChartSeries(new Index() { Val =
new UInt32Value(i) },
new Order() { Val = new UInt32Value(i) },
new SeriesText(new NumericValue() { Text = key })));
StringLiteral strLit = barChartSeries.AppendChild<CategoryAxisData>(new CategoryAxisData()).AppendChild<StringLiteral>(new StringLiteral());
strLit.Append(new PointCount() { Val = new UInt32Value(1U) });
strLit.AppendChild<StringPoint>(new StringPoint() { Index = new UInt32Value(0U) }).Append(new NumericValue(title));
NumberLiteral numLit = barChartSeries.AppendChild<DocumentFormat.OpenXml.Drawing.Charts.Values>(
new DocumentFormat.OpenXml.Drawing.Charts.Values()).AppendChild<NumberLiteral>(new NumberLiteral());
numLit.Append(new FormatCode("General"));
numLit.Append(new PointCount() { Val = new UInt32Value(1U) });
numLit.AppendChild<NumericPoint>(new NumericPoint() { Index = new UInt32Value(0u) }).Append
(new NumericValue(data[key].ToString()));
i++;
}
barChart.Append(new AxisId() { Val = new UInt32Value(48650112u) });
barChart.Append(new AxisId() { Val = new UInt32Value(48672768u) });
// Add the Category Axis.
CategoryAxis catAx = plotArea.AppendChild<CategoryAxis>(new CategoryAxis(new AxisId()
{ Val = new UInt32Value(48650112u) }, new Scaling(new Orientation() { Val = new EnumValue<DocumentFormat.
OpenXml.Drawing.Charts.OrientationValues>( DocumentFormat.OpenXml.Drawing.Charts.OrientationValues.MinMax) }),
new AxisPosition() { Val = new EnumValue<AxisPositionValues>(AxisPositionValues.Bottom) },
new TickLabelPosition() { Val = new EnumValue<TickLabelPositionValues>(TickLabelPositionValues.NextTo) },
new CrossingAxis() { Val = new UInt32Value(48672768U) },
new Crosses() { Val = new EnumValue<CrossesValues>(CrossesValues.AutoZero) },
new AutoLabeled() { Val = new BooleanValue(true) },
new LabelAlignment() { Val = new EnumValue<LabelAlignmentValues>(LabelAlignmentValues.Center) },
new LabelOffset() { Val = new UInt16Value((ushort)100) }));
// Add the Value Axis.
ValueAxis valAx = plotArea.AppendChild<ValueAxis>(new ValueAxis(new AxisId() { Val = new UInt32Value(48672768u) },
new Scaling(new Orientation() { Val = new EnumValue<DocumentFormat.OpenXml.Drawing.Charts.OrientationValues>(
DocumentFormat.OpenXml.Drawing.Charts.OrientationValues.MinMax) }),
new AxisPosition() { Val = new EnumValue<AxisPositionValues>(AxisPositionValues.Left) },
new MajorGridlines(),
new DocumentFormat.OpenXml.Drawing.Charts.NumberingFormat() { FormatCode = new StringValue("General"),
SourceLinked = new BooleanValue(true) }, new TickLabelPosition() { Val = new EnumValue<TickLabelPositionValues>
(TickLabelPositionValues.NextTo) }, new CrossingAxis() { Val = new UInt32Value(48650112U) },
new Crosses() { Val = new EnumValue<CrossesValues>(CrossesValues.AutoZero) },
new CrossBetween() { Val = new EnumValue<CrossBetweenValues>(CrossBetweenValues.Between) }));
// Add the chart Legend.
Legend legend = chart.AppendChild<Legend>(new Legend(new LegendPosition() { Val = new EnumValue<LegendPositionValues>(LegendPositionValues.Right) },
new Layout()));
chart.Append(new PlotVisibleOnly() { Val = new BooleanValue(true) });
// Save the chart part.
chartPart.ChartSpace.Save();
// Position the chart on the worksheet using a TwoCellAnchor object.
drawingsPart.WorksheetDrawing = new WorksheetDrawing();
TwoCellAnchor twoCellAnchor = drawingsPart.WorksheetDrawing.AppendChild<TwoCellAnchor>(new TwoCellAnchor());
twoCellAnchor.Append(new DocumentFormat.OpenXml.Drawing.Spreadsheet.FromMarker(new ColumnId("9"),
new ColumnOffset("581025"),
new RowId("17"),
new RowOffset("114300")));
twoCellAnchor.Append(new DocumentFormat.OpenXml.Drawing.Spreadsheet.ToMarker(new ColumnId("17"),
new ColumnOffset("276225"),
new RowId("32"),
new RowOffset("0")));
// Append a GraphicFrame to the TwoCellAnchor object.
DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame graphicFrame =
twoCellAnchor.AppendChild<DocumentFormat.OpenXml.
Drawing.Spreadsheet.GraphicFrame>(new DocumentFormat.OpenXml.Drawing.
Spreadsheet.GraphicFrame());
graphicFrame.Macro = "";
graphicFrame.Append(new DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualGraphicFrameProperties(
new DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualDrawingProperties() { Id = new UInt32Value(2u), Name = "Chart 1" },
new DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualGraphicFrameDrawingProperties()));
graphicFrame.Append(new Transform(new Offset() { X = 0L, Y = 0L },
new Extents() { Cx = 0L, Cy = 0L }));
graphicFrame.Append(new Graphic(new GraphicData(new ChartReference() { Id = drawingsPart.GetIdOfPart(chartPart) })
{ Uri = "https://schemas.openxmlformats.org/drawingml/2006/chart" }));
twoCellAnchor.Append(new ClientData());
// Save the WorksheetDrawing object.
drawingsPart.WorksheetDrawing.Save();
}
}
' Given a document name, a worksheet name, a chart title, and a Dictionary collection of text keys
' and corresponding integer data, creates a column chart with the text as the series
' and the integers as the values.
Private Sub InsertChartInSpreadsheet(ByVal docName As String, ByVal worksheetName As String, _
ByVal title As String, ByVal data As Dictionary(Of String, Integer))
' Open the document for editing.
Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True)
Dim sheets As IEnumerable(Of Sheet) = _
document.WorkbookPart.Workbook.Descendants(Of Sheet)() _
.Where(Function(s) s.Name = worksheetName)
If sheets.Count() = 0 Then
' The specified worksheet does not exist.
Return
End If
Dim worksheetPart As WorksheetPart = _
CType(document.WorkbookPart.GetPartById(sheets.First().Id), WorksheetPart)
' Add a new drawing to the worksheet.
Dim drawingsPart As DrawingsPart = worksheetPart.AddNewPart(Of DrawingsPart)()
worksheetPart.Worksheet.Append(New DocumentFormat.OpenXml.Spreadsheet.Drawing() With {.Id = _
worksheetPart.GetIdOfPart(drawingsPart)})
worksheetPart.Worksheet.Save()
' Add a new chart and set the chart language to English-US.
Dim chartPart As ChartPart = drawingsPart.AddNewPart(Of ChartPart)()
chartPart.ChartSpace = New ChartSpace()
chartPart.ChartSpace.Append(New EditingLanguage() With {.Val = _
New StringValue("en-US")})
Dim chart As DocumentFormat.OpenXml.Drawing.Charts.Chart = _
chartPart.ChartSpace.AppendChild(Of DocumentFormat.OpenXml.Drawing.Charts _
.Chart)(New DocumentFormat.OpenXml.Drawing.Charts.Chart())
' Create a new clustered column chart.
Dim plotArea As PlotArea = chart.AppendChild(Of PlotArea)(New PlotArea())
Dim layout As Layout = plotArea.AppendChild(Of Layout)(New Layout())
Dim barChart As BarChart = plotArea.AppendChild(Of BarChart)(New BarChart _
(New BarDirection() With {.Val = New EnumValue(Of BarDirectionValues) _
(BarDirectionValues.Column)}, New BarGrouping() With {.Val = New EnumValue _
(Of BarGroupingValues)(BarGroupingValues.Clustered)}))
Dim i As UInteger = 0
' Iterate through each key in the Dictionary collection and add the key to the chart Series
' and add the corresponding value to the chart Values.
For Each key As String In data.Keys
Dim barChartSeries As BarChartSeries = barChart.AppendChild(Of BarChartSeries) _
(New BarChartSeries(New Index() With {.Val = New UInt32Value(i)}, New Order() _
With {.Val = New UInt32Value(i)}, New SeriesText(New NumericValue() With {.Text = key})))
Dim strLit As StringLiteral = barChartSeries.AppendChild(Of CategoryAxisData) _
(New CategoryAxisData()).AppendChild(Of StringLiteral)(New StringLiteral())
strLit.Append(New PointCount() With {.Val = New UInt32Value(1UI)})
strLit.AppendChild(Of StringPoint)(New StringPoint() With {.Index = _
New UInt32Value(0UI)}).Append(New NumericValue(title))
Dim numLit As NumberLiteral = barChartSeries.AppendChild _
(Of DocumentFormat.OpenXml.Drawing.Charts.Values)(New DocumentFormat _
.OpenXml.Drawing.Charts.Values()).AppendChild(Of NumberLiteral)(New NumberLiteral())
numLit.Append(New FormatCode("General"))
numLit.Append(New PointCount() With {.Val = New UInt32Value(1UI)})
numLit.AppendChild(Of NumericPoint)(New NumericPoint() With {.Index = _
New UInt32Value(0UI)}).Append(New NumericValue(data(key).ToString()))
i += 1
Next key
barChart.Append(New AxisId() With {.Val = New UInt32Value(48650112UI)})
barChart.Append(New AxisId() With {.Val = New UInt32Value(48672768UI)})
' Add the Category Axis.
Dim catAx As CategoryAxis = plotArea.AppendChild(Of CategoryAxis) _
(New CategoryAxis(New AxisId() With {.Val = New UInt32Value(48650112UI)}, New Scaling(New Orientation() With {.Val = New EnumValue(Of DocumentFormat.OpenXml.Drawing.Charts.OrientationValues)(DocumentFormat.OpenXml.Drawing.Charts.OrientationValues.MinMax)}), New AxisPosition() With {.Val = New EnumValue(Of AxisPositionValues)(AxisPositionValues.Bottom)}, New TickLabelPosition() With {.Val = New EnumValue(Of TickLabelPositionValues)(TickLabelPositionValues.NextTo)}, New CrossingAxis() With {.Val = New UInt32Value(48672768UI)}, New Crosses() With {.Val = New EnumValue(Of CrossesValues)(CrossesValues.AutoZero)}, New AutoLabeled() With {.Val = New BooleanValue(True)}, New LabelAlignment() With {.Val = New EnumValue(Of LabelAlignmentValues)(LabelAlignmentValues.Center)}, New LabelOffset() With {.Val = New UInt16Value(CUShort(100))}))
' Add the Value Axis.
Dim valAx As ValueAxis = plotArea.AppendChild(Of ValueAxis)(New ValueAxis _
(New AxisId() With {.Val = New UInt32Value(48672768UI)}, New Scaling(New _
Orientation() With {.Val = New EnumValue(Of DocumentFormat.OpenXml.Drawing _
.Charts.OrientationValues)(DocumentFormat.OpenXml.Drawing.Charts.OrientationValues.MinMax)}), _
New AxisPosition() With {.Val = New EnumValue(Of AxisPositionValues)(AxisPositionValues.Left)}, _
New MajorGridlines(), New DocumentFormat.OpenXml.Drawing.Charts.NumberingFormat() With {.FormatCode = _
New StringValue("General"), .SourceLinked = New BooleanValue(True)}, New TickLabelPosition() With _
{.Val = New EnumValue(Of TickLabelPositionValues)(TickLabelPositionValues.NextTo)}, New CrossingAxis() _
With {.Val = New UInt32Value(48650112UI)}, New Crosses() With {.Val = New EnumValue(Of CrossesValues) _
(CrossesValues.AutoZero)}, New CrossBetween() With {.Val = New EnumValue(Of CrossBetweenValues) _
(CrossBetweenValues.Between)}))
' Add the chart Legend.
Dim legend As Legend = chart.AppendChild(Of Legend)(New Legend(New LegendPosition() _
With {.Val = New EnumValue(Of LegendPositionValues)(LegendPositionValues.Right)}, New Layout()))
chart.Append(New PlotVisibleOnly() With {.Val = New BooleanValue(True)})
' Save the chart part.
chartPart.ChartSpace.Save()
' Position the chart on the worksheet using a TwoCellAnchor object.
drawingsPart.WorksheetDrawing = New WorksheetDrawing()
Dim twoCellAnchor As TwoCellAnchor = drawingsPart.WorksheetDrawing.AppendChild(Of _
TwoCellAnchor)(New TwoCellAnchor())
twoCellAnchor.Append(New DocumentFormat.OpenXml.Drawing.Spreadsheet.FromMarker(New _
ColumnId("9"), New ColumnOffset("581025"), New RowId("17"), New RowOffset("114300")))
twoCellAnchor.Append(New DocumentFormat.OpenXml.Drawing.Spreadsheet.ToMarker(New _
ColumnId("17"), New ColumnOffset("276225"), New RowId("32"), New RowOffset("0")))
' Append a GraphicFrame to the TwoCellAnchor object.
Dim graphicFrame As DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame = _
twoCellAnchor.AppendChild(Of DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame) _
(New DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame())
graphicFrame.Macro = ""
graphicFrame.Append(New DocumentFormat.OpenXml.Drawing.Spreadsheet _
.NonVisualGraphicFrameProperties(New DocumentFormat.OpenXml.Drawing.Spreadsheet. _
NonVisualDrawingProperties() With {.Id = New UInt32Value(2UI), .Name = "Chart 1"}, _
New DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualGraphicFrameDrawingProperties()))
graphicFrame.Append(New Transform(New Offset() With {.X = 0L, .Y = 0L}, _
New Extents() With {.Cx = 0L, .Cy = 0L}))
graphicFrame.Append(New Graphic(New GraphicData(New ChartReference() With _
{.Id = drawingsPart.GetIdOfPart(chartPart)}) With {.Uri = _
"https://schemas.openxmlformats.org/drawingml/2006/chart"}))
twoCellAnchor.Append(New ClientData())
' Save the WorksheetDrawing object.
drawingsPart.WorksheetDrawing.Save()
End Using
End Sub