国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

使用OpenXML庫替換docx文檔(Word文檔)中的特定字段

這篇具有很好參考價值的文章主要介紹了使用OpenXML庫替換docx文檔(Word文檔)中的特定字段。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

在批量生成Word文檔的應用中,最常見的需求莫過于替換掉文檔中的特定字段以生成新的文檔。利用OpenXML庫可輕松實現(xiàn)這一需求。

僅限文本內(nèi)容的不完善版本

首先放出最簡單然而有bug的版本:

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

//使用OpenXml SDK 2.5打開Word文檔,并將里面的目標字段替換成指定的值
WordprocessingDocument wordDoc = WordprocessingDocument.Open("word.docx", true);
var body = wordDoc.MainDocumentPart!.Document.Body;
var paras = body!.Elements<Paragraph>();
foreach (var para in paras)
{
    var runs = para.Elements<Run>();
    foreach (var run in runs)
    {
        var texts = run.Elements<Text>();
        foreach (var text in texts)
        {
            if (text.Text.Contains("首席針頭"))
            {
                text.Text = text.Text.Replace("首席針頭", "吃席針頭");
            }
        }
    }
}
//保存文檔
wordDoc.Save();
//釋放資源
wordDoc.Dispose();

該版本的原理是遍歷word文檔中的每個段落,搜索段落中的每個文字字段對象,如果找到匹配的值就將其替換成目標值。

該操作存在問題在于有時候看起來連在一起的文字對象是存儲在不同的文字字段對象(run)中的(分開的原因大概率是格式不統(tǒng)一,但有時看著格式完全一樣也會被分開,魔性),比如下面的文檔:

使用OpenXML庫替換docx文檔(Word文檔)中的特定字段

“首席針頭”這個詞組就被分開成“首席”和“針頭”兩個不同的文字字段對象進行存儲。在這種情況下遍歷對象時就無法實現(xiàn)特定字段的匹配。

僅限文本內(nèi)容的完善版本

要解決這個問題也不難,特定字段可能被分開,我們就將段落里面的所有字段記錄下來,然后合并起來看看是否包含該字段。如果是,則檢測特定字段在哪幾個run中,然后將這幾個run合并起來,最后再進行特定字段的替換即可。代碼如下:

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using static System.Net.Mime.MediaTypeNames;
using System.Text;
using Text = DocumentFormat.OpenXml.Wordprocessing.Text;



//合并目標范圍內(nèi)的run
void mergeRuns(IEnumerable<Run> runs, string[] copy_text)
{
    //找到特定字段所在的第一個run的位置
    int start = 0;
    while (true)
    {
        string sub_str = "";
        for (int i = start; i < runs.Count(); i++)
        {
            sub_str += copy_text[i];
        }
        if (!sub_str.Contains("首席針頭"))
        {
            start--;
            break;
        }
        else
        {
            start++;
        }
    }
    //找到特定字段所在的最后一個run的位置
    string inner_str = "";//范圍內(nèi)的字符串
    int end = runs.Count();
    while (true)
    {
        string sub_str = "";
        for (int i = start; i < end; i++)
        {
            sub_str += copy_text[i];
        }
        if (!sub_str.Contains("首席針頭"))
        {
            end++;
            break;
        }
        else
        {
            inner_str = sub_str;
            end--;
        }
    }
    //將范圍內(nèi)的run合并在一起
    int sel_pt = 0;
    foreach (var run in runs)
    {
        if (sel_pt == start)
        {
            var texts = run.Elements<Text>();
            //將run里面的文字改為inner_str的內(nèi)容
            int num = 0;
            foreach (var mytext in texts)
            {
                if (num == 0)
                {
                    mytext.Text = inner_str;
                }
                else
                {
                    mytext.Text = "";
                }
                num++;
            }
        }
        else if (sel_pt > start && sel_pt < end)//將多余的runs清空
        {
            var texts = run.Elements<Text>();
            foreach (var mytext in texts)
            {
                mytext.Text = "";
            }
        }
        sel_pt++;
    }
}

void replaceTextInParas(IEnumerable<Paragraph> paras)
{
    //遍歷文本的所有段落
    foreach (var para in paras)
    {
        while (true)
        {
            var runs = para.Elements<Run>();
            string[] copy_text = new string[runs.Count()];
            int pt = 0;
            foreach (var run in runs)
            {
                var texts = run.Elements<Text>();
                //第一遍先遍歷,把run內(nèi)部的目標字段替換掉,并構(gòu)建數(shù)組記錄下所有的run
                //創(chuàng)建長度和texts個數(shù)一樣的數(shù)組,用于記錄每個text的內(nèi)容
                foreach (var text in texts)
                {
                    if (text.Text.Contains("首席針頭"))
                    {
                        text.Text = text.Text.Replace("首席針頭", "吃席針頭");
                    }
                    copy_text[pt] += text.Text;
                }
                pt++;
            }
            //將字符串拼接在一塊,看看是否存在目標字段
            string str = string.Join("", copy_text);

            //如果存在目標字段,則將范圍內(nèi)的run合并在一起,然后再替換一次,直到不存在目標字段
            if (str.Contains("首席針頭"))
            {
                mergeRuns(runs, copy_text);
            }
            else
            {
                break;
            }
        }
    }
}

//文檔讀取
WordprocessingDocument wordDoc = WordprocessingDocument.Open("word.docx", true);
//獲取文檔的主體
var body = wordDoc.MainDocumentPart!.Document.Body;
//獲取文檔的所有段落
var paras = body!.Elements<Paragraph>();
//替換文檔段落中的目標字段
replaceTextInParas(paras);
//保存文檔
wordDoc.Save();
//釋放資源
wordDoc.Dispose();

文本內(nèi)容+表格內(nèi)容的完善版本

當然,該版本僅限于文本內(nèi)容,對于表格中的內(nèi)容是無法替換的,原因在于我們在遍歷替換的時候并沒有遍歷表格中的段落。遍歷表格中的單元格段落寫起來很簡單,完整代碼如下:

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using static System.Net.Mime.MediaTypeNames;
using System.Text;
using Text = DocumentFormat.OpenXml.Wordprocessing.Text;

//合并目標范圍內(nèi)的run
void mergeRuns(IEnumerable<Run> runs, string[] copy_text)
{
    //找到特定字段所在的第一個run的位置
    int start = 0;
    while (true)
    {
        string sub_str = "";
        for (int i = start; i < runs.Count(); i++)
        {
            sub_str += copy_text[i];
        }
        if (!sub_str.Contains("首席針頭"))
        {
            start--;
            break;
        }
        else
        {
            start++;
        }
    }
    //找到特定字段所在的最后一個run的位置
    string inner_str = "";//范圍內(nèi)的字符串
    int end = runs.Count();
    while (true)
    {
        string sub_str = "";
        for (int i = start; i < end; i++)
        {
            sub_str += copy_text[i];
        }
        if (!sub_str.Contains("首席針頭"))
        {
            end++;
            break;
        }
        else
        {
            inner_str = sub_str;
            end--;
        }
    }
    //將范圍內(nèi)的run合并在一起
    int sel_pt = 0;
    foreach (var run in runs)
    {
        if (sel_pt == start)
        {
            var texts = run.Elements<Text>();
            //將run里面的文字改為inner_str的內(nèi)容
            int num = 0;
            foreach (var mytext in texts)
            {
                if (num == 0)
                {
                    mytext.Text = inner_str;
                }
                else
                {
                    mytext.Text = "";
                }
                num++;
            }
        }
        else if (sel_pt > start && sel_pt < end)//將多余的runs清空
        {
            var texts = run.Elements<Text>();
            foreach (var mytext in texts)
            {
                mytext.Text = "";
            }
        }
        sel_pt++;
    }
}

void replaceTextInParas(IEnumerable<Paragraph> paras)
{
    //遍歷文本的所有段落
    foreach (var para in paras)
    {
        while (true)
        {
            var runs = para.Elements<Run>();
            string[] copy_text = new string[runs.Count()];
            int pt = 0;
            foreach (var run in runs)
            {
                var texts = run.Elements<Text>();
                //第一遍先遍歷,把run內(nèi)部的目標字段替換掉,并構(gòu)建數(shù)組記錄下所有的run
                //創(chuàng)建長度和texts個數(shù)一樣的數(shù)組,用于記錄每個text的內(nèi)容
                foreach (var text in texts)
                {
                    if (text.Text.Contains("首席針頭"))
                    {
                        text.Text = text.Text.Replace("首席針頭", "吃席針頭");
                    }
                    copy_text[pt] += text.Text;
                }
                pt++;
            }
            //將字符串拼接在一塊,看看是否存在目標字段
            string str = string.Join("", copy_text);

            //如果存在目標字段,則將范圍內(nèi)的run合并在一起,然后再替換一次,直到不存在目標字段
            if (str.Contains("首席針頭"))
            {
                mergeRuns(runs, copy_text);
            }
            else
            {
                break;
            }
        }
    }
}

//文檔讀取
WordprocessingDocument wordDoc = WordprocessingDocument.Open("word.docx", true);
//獲取文檔的主體
var body = wordDoc.MainDocumentPart!.Document.Body;
//獲取文檔的所有段落
var paras = body!.Elements<Paragraph>();
//替換文檔段落中的目標字段
replaceTextInParas(paras);

//獲取文檔的所有表格
var tables = body!.Elements<Table>();
//遍歷表格
foreach (var table in tables)
{
    //獲取表格的所有行
    var rows = table.Elements<TableRow>();
    //遍歷行
    foreach (var row in rows)
    {
        //獲取行的所有單元格
        var cells = row.Elements<TableCell>();
        //遍歷單元格
        foreach (var cell in cells)
        {
            //獲取單元格的所有段落
            var cell_paras = cell.Elements<Paragraph>();
            //替換單元格段落中的目標字段
            replaceTextInParas(cell_paras);
        }
    }
}

//保存文檔
wordDoc.Save();
//釋放資源
wordDoc.Dispose();

到此,我們就完美解決了docx文檔(Word文檔)中特定字段的替換問題啦。文章來源地址http://www.zghlxwxcb.cn/news/detail-508533.html

到了這里,關(guān)于使用OpenXML庫替換docx文檔(Word文檔)中的特定字段的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • 【python】使用docx獲取word文檔的標題等級、大綱等級和編號等級

    在Microsoft Word中: 【標題X】是一個樣式,一般來說,【標題1】樣式的大綱級別是1級。 大綱級別一般用于頁面導航和生成目錄??梢杂益I文字-段落里查看/設置大綱的級別。設置成【x級】后左側(cè)導航欄就會顯示。 編號等級就是大家熟知的項目編號,常用于正文。 基本沒有一

    2024年02月03日
    瀏覽(23)
  • Java使用spire進行word文檔的替換

    Java使用spire進行word文檔的替換

    今天遇到一個需求,需要對word模板進行替換制定的變量 在網(wǎng)上找了很多方案,做了很多的demo,下面就把我覺得比較簡單的一種分享給大家 本次的主角是:spire.doc Spire.Doc for .NET 是一款專門對 Word 文檔進行操作的 .NET類庫。這款控件的主要功能在于幫助開發(fā)人員輕松快捷高效

    2024年02月05日
    瀏覽(43)
  • Node.js 使用 officecrypto-tool 讀取加密的 Excel (xls, xlsx) 和 Word( docx)文檔

    Node.js 使用 officecrypto-tool 讀取加密的 Excel (xls, xlsx) 和 Word( docx)文檔, 還支持 xlsx 和 docx 文件的加密(具體使用看文檔)。暫時不支持doc文件的解密 傳送門:officecrypto-tool 讀取加密的 Excel 示例 讀取加密的 Word 示例 使用:mammoth officecrypto-tool 使用其他的word讀取庫也是一樣的道理

    2024年02月10日
    瀏覽(37)
  • 【word】【python】圖片字段替換

    在 Word 文檔中添加一個特殊的標記(例如:{image_placeholder}),這將充當圖片占位符。 使用 python-docx 庫打開 Word 文檔。 查找占位符并替換為圖片。 保存更改后的 Word 文檔。 將 your_word_document.docx 替換為包含占位符的 Word 文檔的文件名,將 your_image.png 替換為要插入的圖片的文

    2024年02月13日
    瀏覽(55)
  • Python+docx實現(xiàn)python對word文檔的編輯

    Python+docx實現(xiàn)python對word文檔的編輯

    ? ? ? ? 該模塊可以通過python代碼來對word文檔進行大批量的編輯。docx它提供了一組功能豐富的函數(shù)和方法,用于創(chuàng)建、修改和讀取Word文檔。下面是 docx 模塊中一些常用的函數(shù)和方法的介紹: 安裝:pip install docx ???????????????? 通過遍歷? doc.paragraphs? 來獲取文檔中

    2024年02月16日
    瀏覽(23)
  • python之python-docx:操作 office word 文檔

    在Python中,有一個名為 python-docx 的庫,它提供了豐富的功能,可以方便地創(chuàng)建、修改和讀取Word文檔。 本文將詳細介紹 python-docx 庫的使用,并提供一些示例來演示其中的功能。為了更好地理解,我們將分為以下幾個方面進行討論: 安裝 python-docx 創(chuàng)建和保存Word文檔 修改現(xiàn)有

    2024年02月12日
    瀏覽(26)
  • Python 實現(xiàn) PDF 到 Word 文檔的高效轉(zhuǎn)換(DOC、DOCX)

    Python 實現(xiàn) PDF 到 Word 文檔的高效轉(zhuǎn)換(DOC、DOCX)

    PDF(Portable Document Format)已成為一種廣泛使用的電子文檔格式。PDF的主要優(yōu)勢是跨平臺,可以在不同設備上呈現(xiàn)一致的外觀。然而,當我們需要對文件內(nèi)容進行編輯或修改,直接編輯PDF文件會非常困難,而且效果也不理想。將PDF文件轉(zhuǎn)換為Word文檔(doc、docx)再進行編輯是一

    2024年02月03日
    瀏覽(30)
  • 借助文檔控件Aspose.Words,將 Word DOC/DOCX 轉(zhuǎn)換為 TXT

    借助文檔控件Aspose.Words,將 Word DOC/DOCX 轉(zhuǎn)換為 TXT

    在文檔處理領(lǐng)域,經(jīng)常需要將 Word 文檔轉(zhuǎn)換為更簡單的純文本格式。無論是出于數(shù)據(jù)提取、內(nèi)容分析還是兼容性原因,將 Word(.doc、.docx)文件轉(zhuǎn)換為純文本(.txt)的能力對于開發(fā)人員來說都是一項寶貴的技能。在這篇博文中,我們將探討如何在 C# 應用程序中將 Word 文檔轉(zhuǎn)換

    2024年01月19日
    瀏覽(26)
  • 開源Word文字替換小工具更新 增加文檔頁眉和頁腳替換功能

    ITGeeker技術(shù)奇客發(fā)布的開源Word文字替換小工具更新到v1.0.1.0版本啦,現(xiàn)已支持Office Word文檔頁眉和頁腳的替換。 同時ITGeeker技術(shù)奇客修復了v1.0.0.0版本因替換數(shù)字引起的in ‘ requires string as left operand, not int錯誤。 開源Word文字替換小工具官方介紹頁面:https://www.itgeeker.net/itgeeke

    2024年02月11日
    瀏覽(20)
  • word文檔批量生成工具(附免費軟件)(按Excel表格內(nèi)容自動替換內(nèi)容生成文檔)

    word文檔批量生成工具(附免費軟件)(按Excel表格內(nèi)容自動替換內(nèi)容生成文檔)

    批量生成word文檔是讓人無比厭惡但有時又不得不做的事情。比如學校要給擬錄取的學生發(fā)通知書,就可能需要批量生成一批只有“姓名”、“學院”和“專業(yè)”不同,其他內(nèi)容都相同的word文檔以供打印(事實上直接生成pdf是更好的選擇,這個以后有心情可以弄一下)。 要實

    2024年02月11日
    瀏覽(29)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包