最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#調(diào)用OpenXml操作word文檔的基本用法介紹

 更新時(shí)間:2026年05月29日 09:14:39   作者:gc_2299  
本文詳細(xì)介紹了使用圖形類(lèi)Drawing將圖表和數(shù)據(jù)保存到Word文檔的方法,強(qiáng)調(diào)了GraphicData類(lèi)型的關(guān)鍵作用并展示了具體代碼實(shí)現(xiàn)和運(yùn)行效果,有需要的小伙伴可以了解下

使用圖形類(lèi)Drawing不僅可以將圖片保存到word文檔,還能將圖表、表格等數(shù)據(jù)保存到word文檔,關(guān)鍵就在于其子類(lèi)型GraphicData支持關(guān)聯(lián)多種類(lèi)型的圖形數(shù)據(jù),本文記錄以嵌入式布局方式向word中插入圖表的基本用法。

主要代碼如下所示:

using A = DocumentFormat.OpenXml.Drawing;
using C=DocumentFormat.OpenXml.Drawing.Charts;
using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;

if(cbInsertChart.Checked)
{
    ChartPart chartPart = mainPart.AddNewPart<ChartPart>();
    string chartPartId = mainPart.GetIdOfPart(chartPart);

    Drawing drawing = CreateChartDrawing(chartPartId, chartPart);
    run.Append(drawing);
}

public Drawing CreateChartDrawing(string relationshipId, ChartPart chartPart)
{
    var chartSpace = new C.ChartSpace();
    chartSpace.AddNamespaceDeclaration("c", "http://schemas.openxmlformats.org/drawingml/2006/chart");
    chartSpace.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
    chartSpace.AppendChild(new C.EditingLanguage { Val = "zh-CN" });

    var chart = new C.Chart();
    chart.AppendChild(new C.AutoTitleDeleted { Val = true });

    var plotArea = new C.PlotArea();

    var barChart = new C.BarChart(
        new C.BarDirection { Val = C.BarDirectionValues.Column },
        new C.BarGrouping { Val = C.BarGroupingValues.Clustered },
        new C.VaryColors { Val = true }
    );

    var series = new C.BarChartSeries(
        new C.Index { Val = 0 },
        new C.Order { Val = 0 },
        new C.SeriesText(new C.NumericValue("測(cè)試數(shù)據(jù)"))
    );

    series.AppendChild(new C.CategoryAxisData(
        new C.StringLiteral(
            new C.PointCount { Val = 4 },
            new C.StringPoint { Index = 0, NumericValue = new C.NumericValue("A") },
            new C.StringPoint { Index = 1, NumericValue = new C.NumericValue("B") },
            new C.StringPoint { Index = 2, NumericValue = new C.NumericValue("C") },
            new C.StringPoint { Index = 3, NumericValue = new C.NumericValue("D") }
        )
    ));

    series.AppendChild(new C.Values(
        new C.NumberLiteral(
            new C.PointCount { Val = 4 },
            new C.NumericPoint { Index = 0, NumericValue = new C.NumericValue("10") },
            new C.NumericPoint { Index = 1, NumericValue = new C.NumericValue("20") },
            new C.NumericPoint { Index = 2, NumericValue = new C.NumericValue("30") },
            new C.NumericPoint { Index = 3, NumericValue = new C.NumericValue("40") }
        )
    ));

    barChart.AppendChild(series);

    // 坐標(biāo)軸
    var catAxis = new C.CategoryAxis(
        new C.AxisId { Val = 100 },
        new C.Scaling(new C.Orientation { Val = C.OrientationValues.MinMax }),
        new C.AxisPosition { Val = C.AxisPositionValues.Bottom },
        new C.CrossingAxis { Val = 200 },
        new C.Crosses { Val = C.CrossesValues.AutoZero },
        new C.TickLabelPosition { Val = C.TickLabelPositionValues.NextTo }
    );

    var valAxis = new C.ValueAxis(
        new C.AxisId { Val = 200 },
        new C.Scaling(new C.Orientation { Val = C.OrientationValues.MinMax }),
        new C.AxisPosition { Val = C.AxisPositionValues.Left },
        new C.CrossingAxis { Val = 100 },
        new C.Crosses { Val = C.CrossesValues.AutoZero },
        new C.TickLabelPosition { Val = C.TickLabelPositionValues.NextTo },
        new C.MajorTickMark { Val = C.TickMarkValues.None },
        new C.MinorTickMark { Val = C.TickMarkValues.None }
    );

    // 讓BarChart引用坐標(biāo)軸ID
    barChart.AppendChild(new C.AxisId { Val = 100 });
    barChart.AppendChild(new C.AxisId { Val = 200 });

    plotArea.Append(barChart, catAxis, valAxis);
    chart.Append(plotArea);

    chartSpace.AppendChild(chart);
    chartSpace.Save(chartPart);

    return new Drawing(
        new DW.Inline(
            new DW.Extent { Cx = 6000000, Cy = 4000000 },
            new DW.EffectExtent { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L },
            new DW.DocProperties { Id = 1, Name = "Chart 1" },
            new DW.NonVisualGraphicFrameDrawingProperties(
                new A.GraphicFrameLocks { NoChangeAspect = true }
            ),
            new A.Graphic(
                new A.GraphicData(
                    new C.ChartReference { Id = relationshipId }
                )
                { Uri = "http://schemas.openxmlformats.org/drawingml/2006/chart" }
            )
        )
    );
}

下面的截圖是程序運(yùn)行效果及word文檔的內(nèi)容截圖。

知識(shí)擴(kuò)展:

使用 Microsoft 官方提供的 Open XML SDK,我們可以直接在 C# 代碼中創(chuàng)建和修改 Word (.docx) 文件,整個(gè)過(guò)程不依賴(lài)本地安裝的 Microsoft Office 軟件,非常適合在服務(wù)器環(huán)境或需要自動(dòng)化批量處理文檔的場(chǎng)景中使用。

核心概念:Open XML SDK 如何表示 Word 文檔?

在開(kāi)始編寫(xiě)代碼之前,先了解一下 Open XML SDK 中三個(gè)最基本的概念,這會(huì)幫助你更好地理解后續(xù)的代碼。

核心元素作用類(lèi)比如何操作?
段落 (Paragraph)代表文檔中的一個(gè)段落,是文本的基本容器像是搭積木時(shí)的“塊”通常需要配合 ParagraphProperties 來(lái)設(shè)置樣式。
文本運(yùn)行 (Run)Run 是 Paragraph 內(nèi)部的子元素,表示一段具有相同格式的連續(xù)文本。一塊積木上可能有不同的顏色,Run 就像給這塊積木的某個(gè)部分涂上特定的顏色。想要改變字體、大小、顏色,都是操作 Run 的屬性,而不是直接去改文本本身。
文本 (Text)Run 內(nèi)部真正的文本載體積木本身文本內(nèi)容就是這個(gè)類(lèi)構(gòu)造函數(shù)里傳進(jìn)去的字符串。

理解了這三個(gè)核心元素間的層級(jí)關(guān)系(Paragraph -> Run -> Text),就能明白如何構(gòu)建文檔的基本內(nèi)容了。

快速上手:從安裝開(kāi)始

準(zhǔn)備環(huán)境: 首先創(chuàng)建一個(gè) C# 項(xiàng)目(控制臺(tái)應(yīng)用、Web API 等均可)。

安裝核心庫(kù): 在 Visual Studio 中使用 NuGet 包管理器,搜索并安裝 DocumentFormat.OpenXml。

引入命名空間: 在需要操作 Word 的代碼文件頂部,添加以下 using 語(yǔ)句。

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.Text.RegularExpressions;

文檔基本操作:打開(kāi)、創(chuàng)建與保存

Open XML SDK 的核心是 WordprocessingDocument 類(lèi),它代表了一個(gè)完整的 Word 文檔包。

打開(kāi)現(xiàn)有文檔進(jìn)行編輯:使用 Open() 方法,第二個(gè)參數(shù)設(shè)為 true 表示以讀/寫(xiě)模式打開(kāi)文件。

// 打開(kāi)文檔路徑下文件進(jìn)行編輯(使用 using 確保資源自動(dòng)釋放)
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(@"C:\test.docx", true))
{
    // 檢查文檔對(duì)象是否為空,避免后續(xù)操作出錯(cuò)
    if (wordDoc == null) throw new ArgumentNullException(nameof(wordDoc));
    // ... 在此處進(jìn)行編輯操作
}

創(chuàng)建一個(gè)新文檔:使用 Create() 方法,此時(shí)需要顯式創(chuàng)建主文檔部件。

// 創(chuàng)建一個(gè)全新的 Word 文檔
using (WordprocessingDocument wordDoc = WordprocessingDocument.Create(@"C:\new.docx", WordprocessingDocumentType.Document))
{
    // 新文檔必須手動(dòng)添加主文檔部件,否則 Word 無(wú)法打開(kāi)[reference:10]
    MainDocumentPart mainPart = wordDoc.AddMainDocumentPart();
    // 初始化文檔結(jié)構(gòu):Document -> Body
    mainPart.Document = new Document();
    mainPart.Document.Body = new Body();
    // ... 在此處向 Body 中添加內(nèi)容
}

注意using 語(yǔ)句會(huì)自動(dòng)處理資源的釋放和文檔的保存。如果一個(gè)新創(chuàng)建的文檔沒(méi)有添加 MainDocumentPart,Word 在打開(kāi)時(shí)會(huì)提示文件損壞。

文本操作:添加與格式化

掌握了上面的基礎(chǔ),就可以嘗試向文檔中添加內(nèi)容了。

添加普通文本段落

// 獲取文檔的 Body 對(duì)象
Body body = wordDoc.MainDocumentPart.Document.Body;

// 創(chuàng)建一個(gè)新段落,必須顯式包含 Run 和 Text 子元素[reference:14]
Paragraph newParagraph = new Paragraph(
    new ParagraphProperties(), // 段落屬性(如對(duì)齊方式)
    new Run(
        new Text("這是新添加的文本內(nèi)容。")
    )
);

// 將新段落追加到 Body 末尾
body.AppendChild(newParagraph);

注意:Open XML 中構(gòu)造段落的正確方式是 Paragraph 內(nèi)必須包含至少一個(gè) Run 元素,Run 內(nèi)必須包含 Text 元素,缺一不可。

添加帶格式的文本(加粗、顏色等)格式設(shè)置作用于 Run 層級(jí),通過(guò) RunProperties 類(lèi)來(lái)實(shí)現(xiàn)。

// 創(chuàng)建一個(gè)帶格式的文本運(yùn)行
Run formattedRun = new Run();

// 1. 設(shè)置運(yùn)行屬性
RunProperties runProperties = new RunProperties();
runProperties.Bold = new Bold() { Val = true };          // 加粗
runProperties.Color = new Color() { Val = "FF0000" };    // 紅色
runProperties.FontSize = new FontSize() { Val = "28" };  // 字號(hào)(28 相當(dāng)于 14 號(hào))
formattedRun.AppendChild(runProperties);

// 2. 添加文本內(nèi)容
formattedRun.AppendChild(new Text("這是加粗、紅色的文本。"));

表格操作:創(chuàng)建簡(jiǎn)單表格

在 Open XML SDK 中,操作表格需要更嚴(yán)謹(jǐn)?shù)刈裱短捉Y(jié)構(gòu)。其最簡(jiǎn)結(jié)構(gòu)如下:

Body -> Paragraph -> Table -> TableRow -> TableCell -> Paragraph -> Run -> Text
// 創(chuàng)建一個(gè) 3 行 2 列的簡(jiǎn)單表格
Table table = new Table();

// 1. 添加表格屬性(例如設(shè)置寬度)
TableProperties tblProp = new TableProperties();
TableWidth tableWidth = new TableWidth() { Width = "5000", Type = TableWidthUnitValues.Dxa };
tblProp.AppendChild(tableWidth);
table.AppendChild(tblProp);

for (int i = 0; i &lt; 3; i++)
{
    TableRow row = new TableRow();
    for (int j = 0; j &lt; 2; j++)
    {
        TableCell cell = new TableCell();
        // **注意**:每個(gè) TableCell 必須包含至少一個(gè) Paragraph 才能顯示內(nèi)容[reference:17]
        cell.AppendChild(new Paragraph(new Run(new Text($"第{i+1}行, 第{j+1}列"))));
        row.AppendChild(cell);
    }
    table.AppendChild(row);
}

// 將表格添加到 Body 中
wordDoc.MainDocumentPart.Document.Body.AppendChild(table);

注意:上文示例中包含更完整的表格樣式(如邊框)設(shè)置,以及合并單元格的實(shí)現(xiàn)方式。

圖片操作:插入圖片到文檔

插入圖片是稍顯復(fù)雜的操作,因?yàn)樗婕霸诎刑砑有碌牟考?/p>

// 插入圖片的完整過(guò)程
// 1. 添加圖片部件
// 使用絕對(duì)路徑讀取圖片文件流[reference:19]
using (FileStream fs = new FileStream(@"C:\test.png", FileMode.Open))
{
    // AddImagePart 時(shí)指定的 ImagePartType 必須嚴(yán)格匹配圖片文件類(lèi)型[reference:20]
    ImagePart imagePart = wordDoc.MainDocumentPart.AddImagePart(ImagePartType.Png);
    imagePart.FeedData(fs);
    string imagePartId = wordDoc.MainDocumentPart.GetIdOfPart(imagePart);

    // 2. 在文檔正文中創(chuàng)建引用圖片的 XML 結(jié)構(gòu)
    // 此處構(gòu)造 Drawing 元素的相關(guān)代碼較長(zhǎng),具體可參考官方文檔,實(shí)現(xiàn)相對(duì)復(fù)雜
}

注意:插入圖片時(shí),圖片文件路徑必須是運(yùn)行時(shí)能訪(fǎng)問(wèn)到的絕對(duì)路徑。完整的 Drawing 元素代碼較復(fù)雜,建議參考官方詳細(xì)示例。

讀取操作:提取文檔內(nèi)容

Open XML SDK 同樣適用于需要從 Word 文檔中提取信息的場(chǎng)景。

/// &lt;summary&gt;
/// 遍歷文檔所有段落,讀取其純文本內(nèi)容
/// &lt;/summary&gt;
public static List&lt;string&gt; ReadAllParagraphs(string filePath)
{
    List&lt;string&gt; allTexts = new List&lt;string&gt;();

    using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(filePath, false)) // 第二個(gè)參數(shù)為 false 表示只讀
    {
        Body body = wordDoc.MainDocumentPart.Document.Body;
        // 遍歷 Body 下所有 Paragraph 元素
        foreach (Paragraph para in body.Elements&lt;Paragraph&gt;())
        {
            // 獲取該段落內(nèi)所有 Run 下的 Text 元素的文本并拼接
            string paragraphText = string.Join("", para.Descendants&lt;Text&gt;().Select(t =&gt; t.Text));
            if (!string.IsNullOrWhiteSpace(paragraphText))
            {
                allTexts.Add(paragraphText);
            }
        }
    }
    return allTexts;
}

注意:對(duì)于含有多級(jí)表格或復(fù)雜嵌套結(jié)構(gòu)的文檔,可能需要使用遞歸或更精確定位的方式來(lái)提取特定區(qū)域的文本。

到此這篇關(guān)于C#調(diào)用OpenXml操作word文檔的基本用法介紹的文章就介紹到這了,更多相關(guān)C# OpenXml操作word內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

南江县| 凤台县| 玉屏| 民权县| 宁国市| 定陶县| 林芝县| 大宁县| 五台县| 青州市| 唐海县| 葵青区| 方山县| 佛学| 固镇县| 甘孜县| 会理县| 西乡县| 柘荣县| 阿城市| 阿巴嘎旗| 永修县| 古浪县| 会宁县| 兴宁市| 宜黄县| 盖州市| 榕江县| 镇沅| 攀枝花市| 盐城市| 东丽区| 甘洛县| 微博| 句容市| 黄大仙区| 田阳县| 衡阳县| 库车县| 义乌市| 扬中市|