WordHelper 类

using NPOI.XWPF.UserModel;
using System;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;

namespace Helper
{
    public class WordHelper
    {
        /// <summary>
        /// model 可以为DataTable 或者 匿名类
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="outPath"></param>
        /// <param name="model"></param>
        public Stream Export(string filePath,object model)
        {
            using (FileStream stream = File.OpenRead(filePath))
            {
                var wordStream = new MemoryStream();
                XWPFDocument doc = new XWPFDocument(stream);
                //遍历段落                  
                foreach (var para in doc.Paragraphs)
                {
                    if (model is DataTable)
                    {
                        ReplaceKeyByDataTable(para, (DataTable)model);
                    }
                    else
                    {
                        ReplaceKey(para, model);
                    }
                }
                //遍历表格      
                var tables = doc.Tables;
                foreach (var table in tables)
                {
                    foreach (var row in table.Rows)
                    {
                        foreach (var cell in row.GetTableCells())
                        {
                            foreach (var para in cell.Paragraphs)
                            {
                                if (model is DataTable)
                                {
                                    ReplaceKeyByDataTable(para,(DataTable) model);
                                }
                                else
                                {
                                    ReplaceKey(para, model);
                                }
                              
                            }
                        }
                    }
                }
               // FileStream out1 = new FileStream(outPath, FileMode.Create);
                doc.Write(wordStream);
                return wordStream;
                //out1.Close();
            }
        }
        public void ReplaceKey(XWPFParagraph para, object model)
        {
            string text = para.ParagraphText;
            var runs = para.Runs;
            string styleid = para.Style;
       
            text = String.Join("", runs.Select(x => x.Text));
            Type t = model.GetType();
            PropertyInfo[] pi = t.GetProperties();
            foreach (PropertyInfo p in pi)
            {
                if (text.Contains("{$" + p.Name + "}"))
                {
                    text = text.Replace("{$" + p.Name + "}", p.GetValue(model, null).ToString());
                }
            }
            int length = runs.Count();
            for (int j = (length - 1); j >= 0; j--)
            {
                para.RemoveRun(j);
            }
            //直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun,把文本附加在当前文本后面, 
            //所以我们不能直接设值,需要先删除当前run,然后再自己手动插入一个新的run。 
            para.InsertNewRun(0).SetText(text, 0);
        }

        public void ReplaceKeyByDataTable(XWPFParagraph para, DataTable model)
        {
            string text = para.ParagraphText;
            var runs = para.Runs;
            string styleid = para.Style;

            text = String.Join("", runs.Select(x => x.Text));
           
            foreach (DataRow p in model.Rows)
            {
                if (CheckIsMatchTemplateValue(text))
                {
                    var columnName = GetValueFromTemplateVar(text, @"{\$", "}");
                    if (model.Columns.Contains(columnName))
                    {
                        text = text.Replace("{$" + columnName + "}", p[columnName].ToString());
                    }
                }
            }
            int length = runs.Count();
            for (int j = (length - 1); j >= 0; j--)
            {
                para.RemoveRun(j);
            }
            //直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun,把文本附加在当前文本后面, 
            //所以我们不能直接设值,需要先删除当前run,然后再自己手动插入一个新的run。 
            para.InsertNewRun(0).SetText(text, 0);
        }

        private bool CheckIsMatchTemplateValue(string value)
        {
            Regex regex = new Regex(@"([{\$][\w\W]*})");
            Match match = regex.Match(value);
            return match.Success;
        }
        private string GetValueFromTemplateVar(string str, string s, string e)
        {
            Regex rg = new Regex("(?<=(" + s + "))[.\\s\\S]*?(?=(" + e + "))", RegexOptions.Multiline | RegexOptions.Singleline);
            return rg.Match(str).Value;
        }
    }
    
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,您是正确的,对不起给您带来了困扰。NPOI 2.4.1版本的`XWPFDocument`没有提供`GetParagraphsOnPage`方法。以下是另一种实现方式,可以获取指定页码的段落列表: ```csharp using NPOI.XWPF.UserModel; using NPOI.OpenXmlFormats.Wordprocessing; using System.Collections.Generic; using System.IO; using System.Linq; public class WordHelper { public static List<XWPFParagraph> GetParagraphsOnPage(XWPFDocument doc, int pageNumber) { List<XWPFParagraph> result = new List<XWPFParagraph>(); // 遍历文档中的所有段落,判断它们所在页码是否等于指定页码 int pageIndex = 1; foreach (var para in doc.Paragraphs) { if (IsParagraphOnPage(para, pageIndex, pageNumber)) { result.Add(para); } // 如果当前段落是分页符,则页码加1 if (para.IsPageBreak) { pageIndex++; } } return result; } private static bool IsParagraphOnPage(XWPFParagraph para, int pageIndex, int targetPageIndex) { // 如果段落所在页码等于目标页码,则返回true if (GetParagraphPageIndex(para, pageIndex) == targetPageIndex) { return true; } // 如果段落所在页码大于目标页码,则返回false if (GetParagraphPageIndex(para, pageIndex) > targetPageIndex) { return false; } // 如果当前段落是最后一个段落,则返回false if (para == para.Document.Paragraphs.LastOrDefault()) { return false; } // 如果当前段落和下一个段落跨页,则返回false if (GetParagraphPageIndex(para, pageIndex) != GetParagraphPageIndex(para.Document.Paragraphs[para.Document.Paragraphs.IndexOf(para) + 1], pageIndex)) { return false; } // 否则递归判断下一个段落 return IsParagraphOnPage(para.Document.Paragraphs[para.Document.Paragraphs.IndexOf(para) + 1], pageIndex, targetPageIndex); } private static int GetParagraphPageIndex(XWPFParagraph para, int startPageIndex) { // 计算指定段落所在页码 int pageIndex = startPageIndex; foreach (var run in para.Runs) { if (run is XWPFRun) { CT_R ctRun = (CT_R)run.GetCTR().Clone(); if (ctRun.Items != null && ctRun.Items.Any(i => i is CT_PageNumber)) { int pageNumber = int.Parse(ctRun.Items.First(i => i is CT_PageNumber).InnerText); if (pageNumber > pageIndex) { pageIndex = pageNumber; } } } } return pageIndex; } } // 使用示例 XWPFDocument doc = new XWPFDocument(new FileStream("your_word_file.docx", FileMode.Open)); List<XWPFParagraph> pageParagraphs = WordHelper.GetParagraphsOnPage(doc, 2); List<XWPFParagraph> copiedParagraphs = new List<XWPFParagraph>(); foreach (XWPFParagraph para in pageParagraphs) { copiedParagraphs.Add(para); } XWPFParagraph lastPara = doc.GetParagraphArray(doc.Paragraphs.Count - 1); foreach (XWPFParagraph para in copiedParagraphs) { // ... } doc.Write(new FileStream("your_modified_word_file.docx", FileMode.Create)); ``` 以上代码通过遍历文档中的所有段落,并逐个判断段落所在页码是否等于指定页码,从而获取指定页码的段落列表。如果一个段落跨多页,需要对该段落进行递归判断。其中,`GetParagraphPageIndex`方法用于计算指定段落所在页码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值