我们是五月的花海 , 用青春拥抱时代 |

兴想事成

园龄:12年10个月粉丝:25关注:97

手动解析word Table模块内容

 

最近来了一个需求, 需要手动解析word ( 好处就是不需要安装office 以及不会有office解析的线程残留),然后就是可以自定义解析规则,比较方便

比如解析这个word里面的内容: 标题,表格的行和列,以及单元格里面的每一个项

 

解决方案

 使用 DocumentFormat.OpenXml.dll + WindowsBase.dll+正则表达式

WindowsBase.dll  和 DocumentFormat.OpenXml.dll 都是微软的,

可以不用安装office 就能得到 对应的 文档( word,excel) 的 xml格式文本内容,缺点是 只支持 docx,xlsx ,

低版本的(doc,xls)读不出来(可能是未按照对应的协议进行排版), 

 

另外再说一个比较 麻烦的问题,  金山wps和 office ,以及其他厂商的,对 word文件 的内部实现不一样,解析的话需要做兼容处理.

以下是主要的对象以及方法:(仅供参考)

复制代码
//引入命名空间

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


using (WordprocessingDocument doc = WordprocessingDocument.Open(stream, false)) { Body body = doc.MainDocumentPart.Document.Body; foreach (var xmlElement in body.Elements<OpenXmlElement>()) { List<string> RowElement = new List<string>(); foreach (var item in xmlElement.ChildElements) { string elementText = item.InnerText.Trim(); if (!string.IsNullOrEmpty(elementText)) { //处理 elementText RowElement.Add(elementText); } } } } string bodyInnerXml = body.InnerXml; //然后通过 正则表达式 "<w:tbl(\\s|>)(.+?)</w:tbl>" 得到 table的个数 /*2.解析 table 对应的 单元格数据*/ foreach (var table in body.Elements<Table>()) { string t_table_xml = table.InnerXml; //通过正则 "<w:tr(\\s|>)(.+?)</w:tr>"); 匹配行的个数 //通过正则"<w:tr(\\s|>)(.+?)</w:tr>", "<w:tc>(.+?)</w:tc>" 匹配列的个数 }
//遍历行 foreach (var tableRow in table.Elements<TableRow>()) { string rowInnerText = tableRow.InnerText; //遍历列 foreach (var tableCell in tableRow.Elements<TableCell>()) { //凡是实现了IEnumerable接口的类,都可以使用foreach循环迭代遍历, 不过很遗憾,没有提供 this[index] 的访问方式 string celInnerXml = tableCell.InnerXml; //要解析 单个item项的内容. 只能通过 正则表达式了, 不同的厂商, 里面的xml内容是不一样的, 所以要做很多的兼容.... if ((celInnerXml.Contains("<w:numPr>")|| celInnerXml.Contains("w:pPr>"))&& celInnerXml.Contains("</w:p>"))
{
           //1.目前来说是这样做兼容的 
           //2.然后通过正则 "<w:numPr(\\s|>)(.+?)</w:p>" 和 "<w:pPr(\\s|>)(.+?)</w:p>" 判断是否有对应的 匹配项

           //3.就算得到了 匹配项,. 里面还有很多的样式代码,要把这些样式代码都替换掉(通过正则 @"<(.[^>]*)>" 进行替换)

           //4.另外还有各种有序符号,无序符号,以及 checkbox框( □ ) 等 标识符, 这些字符贴到网页上 的code值好像都是9633 

// 5.在 word里面 无序符号 是通过特殊的标签定义的,不同厂商的标签不一样,要识别不同厂商的只能做兼容处理
      }

   }

}

复制代码

贴3个比较有用的方法

复制代码
        /// <summary>
        /// 去除所有Html标签,以及换行,制表符
        /// </summary>
        /// <param name="Htmlstring">要格式化的字符串</param>
        /// <returns></returns>
        public static string NoHTML(string Htmlstring) //去除HTML标记   
        {
            //删除脚本   
            Htmlstring = Regex.Replace(Htmlstring, @"<script.+?</script>", "", RegexOptions.Multiline | RegexOptions.IgnoreCase);
            //删除HTML   
            Htmlstring = Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
            
            Htmlstring = Regex.Replace(Htmlstring, @"-->", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"<!--.*", "", RegexOptions.IgnoreCase);

            Htmlstring = Regex.Replace(Htmlstring, @"&(quot|#34);", "/", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(amp|#38);", "&", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(lt|#60);", "<", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(gt|#62);", ">", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(nbsp|#160);", " ", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(iexcl|#161);", "/xa1", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(cent|#162);", "/xa2", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(pound|#163);", "/xa3", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(copy|#169);", "/xa9", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&#(/d+);", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"\r\n|\n|\t", "");

         
            return Htmlstring;
        }
复制代码

 

复制代码
        public static string NoXml(string xmlString,string replaceEmpty="")//去除xml标记
        {
            //删除脚本   
           // xmlString = Regex.Replace(xmlString, @"<script.+?</script>", "", RegexOptions.Multiline | RegexOptions.IgnoreCase);
            //删除<>标签内的内容   
            xmlString = Regex.Replace(xmlString, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
            if (replaceEmpty.Length>0)
            {
                xmlString = xmlString.Replace(replaceEmpty, "");
            }
            xmlString = xmlString.Replace("", "");
            return xmlString;
        }


复制代码
复制代码
        /// <summary>
        /// 得到所有(.+?)匹配到的集合
        /// </summary>
        /// <param name="regexStr">带(.+?)的正则表达式</param>
        /// <param name="inputHtml">Html源代码</param>
        /// <returns></returns>
        public static List<string> GetMatchRegexList(string regexStr, string inputHtml)
        {
            List<string>list = new List<string>();
            StringBuilder sbulider = new StringBuilder();
            if (!string.IsNullOrEmpty(regexStr))
            {
                Regex regex = new Regex(regexStr, RegexOptions.Singleline | RegexOptions.IgnoreCase);
                if (regex.IsMatch(inputHtml))
                {
                    MatchCollection mc = regex.Matches(inputHtml);
                    for (int i = 0; i < mc.Count; i++)
                    {
                        list.Add(mc[i].Groups[0].Value);
                    }
                }
            }
            return list;
        }
复制代码

 

复制代码
  GetInnerHtml(p_text:string):string{

    //p_text = p_text.replace(//g,"@rn");
    p_text = p_text.replace(/□/g,''); //这个是 9633
    p_text = p_text.replace(/<span style="white-space:pre">/g,'@rn');//兼容处理
    p_text = p_text.replace(/<br>/g,'@rn');//换行
    p_text = p_text.replace(/<\/br>/g,'@rn');//换行
    p_text = p_text.replace(/<\/p>/g,'<\/p>@rn');//换行
    p_text = p_text.replace(/<(.[^>]*)>/g,'');//去除<>标签块的内容
    
    p_text = p_text.replace(/@rn /g,'@rn'); //兼容处理
    p_text = p_text.replace(/n /g,''); //兼容处理,一些稀奇古怪的东西     
    p_text = p_text.replace(/@rn/g,'@rn');//多个换行,替换为一个换行
    //... 其他的兼容性代码 
     return p_text;
   }
  //其他代码
  // console.log(("□".charCodeAt(0))); //无序符号,粘贴到网页里面, 变成了 这个字符, 经测定,该字符的 code值 为 9633
复制代码

 


另外如果是 直接将word里面的内容, 粘贴到 网页上的div里面, 然后获取innerHTML 代码, 传到后台, 需要做一下预处理
比如我这里标记换行, 用的是 "@rn" 字符


 

posted @   兴想事成  阅读(442)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
历史上的今天:
2016-07-13 [SSIS] 在脚本里面使用数据库连接字符串进行查询等处理, 入坑
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 Good-bye My Loneliness ZARD
  2. 2 Say OK Vanessa Hudgens
  3. 3 All The Love In The World The Corrs
  4. 4 Adesso E Fortuna ~炎と永遠~ 加藤いづみ
All The Love In The World - The Corrs
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

I'm not looking for someone to talk to

I've got my friends, I'm more than O.K.

I've got more than a girl could wish for

I live my dreams but it's not all they say

Still I believe (I'm missing) I'm missing something real

I need someone who really sees me...

(Don't wanna wake...) Don't wanna wake up alone anymore

Still believing you'll walk through my door

All I need is to know it's for sure

Then I'll give... all the love in the world

I've often wondered if love's an illusion

Just to get you through the loneliest days

I can't criticize it

I have no hesitation

My imagination just stole me away

(Still...) Still I believe

(I'm missing) I'm missing something real

I need someone who really sees me...

(Don't wanna wake...) Don't wanna wake up alone anymore (

Still believing you'll walk through my door

All I need is to know it's for sure

Then I'll give... all the love in the world

Love's for a lifetime not for a moment

So how could I throw it away

Yeah I'm only human

And nights grow colder

With no-one to love me that way

Yeah I need someone who really sees me...

(Don't wanna wake...) And i won't wake up alone anymore (

Still believing you'll walk through my door

You'll reach for me and I'll know it's for sure

Then I'll give all the love in the world

(don’t want to wake up alone anymore) alone (

(don’t want to wake up alone) just reach for me (

(don’t want to wake up alone) just don’t want to be alone

(don’t want to wake up alone) don’t want to wake up alone

(don’t want to wake up alone) let me know it’s sure

(don’t want to wake up alone) still believing someone

(don’t want to wake up alone) will reach for me

(don’t want to wake up alone) let me know it’s sure