【问题标题】:How to add a barchart to a OpenXML created document如何将条形图添加到 OpenXML 创建的文档
【发布时间】:2020-04-10 19:47:08
【问题描述】:

我的 C# 应用程序使用 OpenXML 创建了一个 MSWord 文档,其中已经包含多个表。最后一部分是添加条形图。我找不到这种情况的好例子。

感谢您的帮助!

我正在从头开始创建文档。开始于:

using (WordprocessingDocument myDoc = WordprocessingDocument.Create(documentStream, WordprocessingDocumentType.Document, autoSave: true))

然后我在 C# 代码中添加新的表格和段落。在我到达条形图之前,所有这些都有效。我找到了一个将饼图插入到 word 文档中的示例项目,但我不明白要转换它的图表类型之间的差异。这是我找到的饼图示例项目:

https://code.msdn.microsoft.com/office/How-to-create-Chart-into-a7d424f6

感谢您的帮助!

【问题讨论】:

  • 我对 OpenXML 不熟悉,但听起来您可能想先进行 Google 搜索,看看其他人已经尝试过什么。您是否尝试过阅读 OpenXML 文档 (msdn.microsoft.com/en-us/library/office/bb448854.aspx)?除非您能更具体地说明您遇到的问题,否则您不太可能获得太多帮助。
  • 到目前为止你尝试过什么?您是从头开始创建文档还是使用模板填写?为了最好地帮助您解决这个问题,我们需要更多地了解您的问题。
  • 将图表添加到 docx 文档并非易事。您找到的示例似乎是一个很好的起点。它插入一个 Pie3DChart。可以使用 BarChart 类型(均来自 DocumentFormat.OpenXml.Drawing.Charts 命名空间)添加条形图。

标签: openxml


【解决方案1】:

要插入基本条形图,我不会查看饼图代码并尝试猜测如何将其转换为条形图。

一种更快的解决方案是使用 Open XML Productivity Tool。它有一个功能,允许您打开 2 个文件,确定两个 Open XML 结构之间的差异,并生成您需要的代码,使第一个文件看起来像第二个文件。

试试这个方法:

  1. Install the Open XML Productivity Tool
  2. 保存您的 Word 文档(添加饼图之前的干净版本)并将其命名为 NoBarChart.docx
  3. 复制NoBarChart.docx 将其命名为WithBarChart.docx
  4. 用 Word 打开WithBarChart.docx 并添加条形图(插入->图表->条形图)。
  5. 使用颜色、格式等设置条形图的样式,以满足您的最终解决方案并保存并关闭。
  6. 运行 Open XML Productivity Tool,然后点击顶部的比较文件按钮。
  7. 选择NoBarChart.docx 作为源,选择WithBarChart.docx 作为目标
  8. 单击文件中突出显示的不同部分,然后单击查看部分差异以查看 XML 中的差异。然后点击查看包代码,该工具将生成代码,使源看起来像目标。

检查它生成的代码,了解如何添加条形图。如果缺少部分代码,您可以使用该工具生成整个 Target 文件。

指向一个简单 WPF 应用程序的链接,该应用程序生成一个带有条形图 is on GitHub 的空白文档。这是文件的图片:

同样的方法可用于生成大多数 Word、Excel 或 PowerPoint 文件以及它们提供的功能。

【讨论】:

  • @Taterhead 我无法从您提供的链接中获取 Open Xml Productive 工具。可以发个链接吗?
  • 试试这个:microsoft.com/en-us/download/details.aspx?id=30425。 OpenXML 生产力工具不是单独的下载。它与 OpenXML SDK 捆绑在一起。在第一个屏幕上向下滚动一点,然后单击红色的下载按钮。在接下来的屏幕上,选中第二个复选框 OpenXMLSDKToolV25.msi 并单击 Next 开始下载。下载 MSI 后,启动下载并接受安装向导屏幕上的默认设置以完成安装。
【解决方案2】:

我按照您遵循的创建饼图的教程进行操作。然后我设法改变它,以便在 Word 文档中插入一个条形图。 希望下面的代码对你有所帮助。 我正在 CreateBarChart 函数中创建一个数据样本,以便在 Barchart 中创建一列。

public static WordprocessingDocument CreateBarChart(WordprocessingDocument document)//List<ChartSubArea> chartList,
    {
        string title = "New Chart";

        Dictionary<string, int> data = new Dictionary<string, int>();
        data.Add("abc", 1);

        // Get MainDocumentPart of Document
        MainDocumentPart mainPart = document.AddMainDocumentPart();
        mainPart.Document = new Document(new Body());

        // Create ChartPart object in Word Document
        ChartPart chartPart = mainPart.AddNewPart<ChartPart>("rId110");

        // the root element of chartPart 
        dc.ChartSpace chartSpace = new dc.ChartSpace();
        chartSpace.Append(new dc.EditingLanguage() { Val = "en-us" });

        // Create Chart 
        dc.Chart chart = new dc.Chart();
        chart.Append(new dc.AutoTitleDeleted() { Val = true });

        // Define the 3D view
        dc.View3D view3D = new dc.View3D();
        view3D.Append(new dc.RotateX() { Val = 30 });
        view3D.Append(new dc.RotateY() { Val = 0 });

        // Intiliazes a new instance of the PlotArea class
        dc.PlotArea plotArea = new dc.PlotArea();
        BarChart barChart = plotArea.AppendChild<BarChart>(new BarChart(new BarDirection()
        { Val = new EnumValue<BarDirectionValues>(BarDirectionValues.Column) },
           new BarGrouping() { Val = new EnumValue<BarGroupingValues>(BarGroupingValues.Clustered) }));

        plotArea.Append(new dc.Layout());


        dc.ChartShapeProperties chartShapePros = new dc.ChartShapeProperties();

        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) }));

        // create child elements of the c:legend element
        dc.Legend legend = new dc.Legend();
        legend.Append(new dc.LegendPosition() { Val = LegendPositionValues.Right });
        dc.Overlay overlay = new dc.Overlay() { Val = false };
        legend.Append(overlay);

        dc.TextProperties textPros = new DocumentFormat.OpenXml.Drawing.Charts.TextProperties();
        textPros.Append(new d.BodyProperties());
        textPros.Append(new d.ListStyle());

        d.Paragraph paragraph = new d.Paragraph();
        d.ParagraphProperties paraPros = new d.ParagraphProperties();
        d.DefaultParagraphProperties defaultParaPros = new d.DefaultParagraphProperties();
        defaultParaPros.Append(new d.LatinFont() { Typeface = "Arial", PitchFamily = 34, CharacterSet = 0 });
        defaultParaPros.Append(new d.ComplexScriptFont() { Typeface = "Arial", PitchFamily = 34, CharacterSet = 0 });
        paraPros.Append(defaultParaPros);
        paragraph.Append(paraPros);
        paragraph.Append(new d.EndParagraphRunProperties() { Language = "en-Us" });

        textPros.Append(paragraph);
        legend.Append(textPros);

        // Append c:view3D, c:plotArea and c:legend elements to the end of c:chart element
        chart.Append(view3D);
        chart.Append(plotArea);
        chart.Append(legend);

        // Append the c:chart element to the end of c:chartSpace element
        chartSpace.Append(chart);

        // Create c:spPr Elements and fill the child elements of it
        chartShapePros = new dc.ChartShapeProperties();
        d.Outline outline = new d.Outline();
        outline.Append(new d.NoFill());
        chartShapePros.Append(outline);

        // Append c:spPr element to the end of c:chartSpace element
        chartSpace.Append(chartShapePros);

        chartPart.ChartSpace = chartSpace;

        // Generate content of the MainDocumentPart
        GeneratePartContent(mainPart);

        return document;

    }
public static void GeneratePartContent(MainDocumentPart mainPart)
    {
        w.Paragraph paragraph = new w.Paragraph() { RsidParagraphAddition = "00C75AEB", RsidRunAdditionDefault = "000F3EFF" };

        // Create a new run that has an inline drawing object
        w.Run run = new w.Run();
        w.Drawing drawing = new w.Drawing();

        dw.Inline inline = new dw.Inline();
        inline.Append(new dw.Extent() { Cx = 5274310L, Cy = 3076575L });
        dw.DocProperties docPros = new dw.DocProperties() { Id = (UInt32Value)1U, Name = "Chart 1" };
        inline.Append(docPros);

        d.Graphic g = new d.Graphic();
        d.GraphicData graphicData = new d.GraphicData() { Uri = "http://schemas.openxmlformats.org/drawingml/2006/chart" };
        dc.ChartReference chartReference = new ChartReference() { Id = "rId110" };
        graphicData.Append(chartReference);
        g.Append(graphicData);
        inline.Append(g);
        drawing.Append(inline);
        run.Append(drawing);
        paragraph.Append(run);

        mainPart.Document.Body.Append(paragraph);
    }

这是我看到的结果。希望这会有所帮助。

【讨论】:

  • 结果看起来不错,代码不是很干净,例如缺少 using 语句。直流。使用 dc = DocumentFormat.OpenXml.Drawing.Charts;但是 BarChart 没有使用前缀 dc,所以我猜你使用的是 DocumentFormat.OpenXml.Drawing.Charts;也是。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多