c# openxml 打开加密 的word读取内容

using System;
using System.IO;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;/// <summary>
/// 使用OpenXML获取文档内容,替代Aspose方式
/// </summary>
/// <param name="path">文档路径</param>
/// <param name="password">密码</param>
/// <returns>文档内容字符串</returns>
public static string GetWordContentByOpenXml(string path, string password)
{try{using (var document = WordprocessingDocument.Open(path, false, new OpenSettings(){Password = password})){if (document.MainDocumentPart?.Document?.Body == null)return null;// 创建StringBuilder来存储文档主体内容var contentBuilder = new StringBuilder();// 获取文档主体,排除页眉页脚var body = document.MainDocumentPart.Document.Body;// 提取主文档内容(不包括页眉页脚)ExtractBodyContent(body, contentBuilder);// 获取原始内容string contentWithoutHeaderFooter = contentBuilder.ToString();// 应用内容清理和格式化string content = CleanContent(contentWithoutHeaderFooter);// 处理特定的截取逻辑int index = content.LastIndexOf("限公司第");if (index > 0){return content.Substring(0, index).Trim();}else{return content;}}}catch (Exception ex){LogManager.WriteError("GetWordContentByOpenXml()", ex.StackTrace?.ToString());return null;}
}/// <summary>
/// 提取文档主体内容,排除页眉页脚
/// </summary>
/// <param name="body">文档主体</param>
/// <param name="contentBuilder">内容构建器</param>
private static void ExtractBodyContent(Body body, StringBuilder contentBuilder)
{// 遍历文档主体中的所有元素foreach (var element in body.Elements()){ExtractElementContent(element, contentBuilder);}
}/// <summary>
/// 递归提取元素内容
/// </summary>
/// <param name="element">OpenXML元素</param>
/// <param name="contentBuilder">内容构建器</param>
private static void ExtractElementContent(OpenXmlElement element, StringBuilder contentBuilder)
{switch (element){case Paragraph paragraph:ExtractParagraphContent(paragraph, contentBuilder);contentBuilder.AppendLine(); // 段落后换行break;case Table table:ExtractTableContent(table, contentBuilder);break;case SectionProperties _:// 跳过节属性,这些通常包含页眉页脚引用break;default:// 递归处理其他容器元素foreach (var childElement in element.Elements()){ExtractElementContent(childElement, contentBuilder);}break;}
}/// <summary>
/// 提取段落内容
/// </summary>
/// <param name="paragraph">段落元素</param>
/// <param name="contentBuilder">内容构建器</param>
private static void ExtractParagraphContent(Paragraph paragraph, StringBuilder contentBuilder)
{foreach (var run in paragraph.Elements<Run>()){foreach (var text in run.Elements<Text>()){contentBuilder.Append(text.Text);}// 处理制表符foreach (var tab in run.Elements<TabChar>()){contentBuilder.Append("\t");}// 处理换行符foreach (var br in run.Elements<Break>()){contentBuilder.AppendLine();}}
}/// <summary>
/// 提取表格内容
/// </summary>
/// <param name="table">表格元素</param>
/// <param name="contentBuilder">内容构建器</param>
private static void ExtractTableContent(Table table, StringBuilder contentBuilder)
{foreach (var row in table.Elements<TableRow>()){foreach (var cell in row.Elements<TableCell>()){foreach (var paragraph in cell.Elements<Paragraph>()){ExtractParagraphContent(paragraph, contentBuilder);}contentBuilder.Append("\t"); // 单元格间用制表符分隔}contentBuilder.AppendLine(); // 表格行后换行}
}/// <summary>
/// 清理和格式化内容,模拟Aspose的清理功能
/// </summary>
/// <param name="content">原始内容</param>
/// <returns>清理后的内容</returns>
private static string CleanContent(string content)
{if (string.IsNullOrEmpty(content))return string.Empty;// 移除多余的空白字符(模拟Tool.TrimAll功能)content = System.Text.RegularExpressions.Regex.Replace(content, @"\s+", " ");content = content.Trim();// 移除多余的换行符content = System.Text.RegularExpressions.Regex.Replace(content, @"\n\s*\n", "\n");// 移除Aspose评估版本的水印文本(虽然OpenXML不会有,但保持兼容性)content = content.Replace("EvaluationOnly.CreatedwithAspose.Words.Copyright2003-2024AsposePtyLtd.", "");// 移除其他可能的控制字符content = System.Text.RegularExpressions.Regex.Replace(content, @"[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]", "");return content.Trim();
}/// <summary>
/// 检查文档是否需要密码
/// </summary>
/// <param name="path">文档路径</param>
/// <returns>是否需要密码</returns>
public static bool IsPasswordRequired(string path)
{try{using (var document = WordprocessingDocument.Open(path, false)){// 如果能正常打开,说明不需要密码return false;}}catch (OpenXmlPackageException ex){// 如果抛出密码相关异常,说明需要密码return ex.Message.Contains("password") || ex.Message.Contains("encrypted") || ex.Message.Contains("protected");}catch{// 其他异常可能也表示需要密码return true;}
}/// <summary>
/// 增强版本:支持更多文档处理选项
/// </summary>
/// <param name="path">文档路径</param>
/// <param name="password">密码</param>
/// <param name="includeHyperlinks">是否包含超链接文本</param>
/// <param name="includeFootnotes">是否包含脚注</param>
/// <returns>文档内容</returns>
public static string GetWordContentByOpenXmlAdvanced(string path, string password, bool includeHyperlinks = false, bool includeFootnotes = false)
{try{using (var document = WordprocessingDocument.Open(path, false, new OpenSettings(){Password = password})){if (document.MainDocumentPart?.Document?.Body == null)return null;var contentBuilder = new StringBuilder();var body = document.MainDocumentPart.Document.Body;// 提取主文档内容ExtractBodyContentAdvanced(body, contentBuilder, includeHyperlinks);// 如果需要包含脚注if (includeFootnotes && document.MainDocumentPart.FootnotesPart != null){ExtractFootnotesContent(document.MainDocumentPart.FootnotesPart, contentBuilder);}string contentWithoutHeaderFooter = contentBuilder.ToString();string content = CleanContent(contentWithoutHeaderFooter);// 应用特定的截取逻辑int index = content.LastIndexOf("公司第");if (index > 0){return content.Substring(0, index).Trim();}else{return content;}}}catch (Exception ex){LogManager.WriteError("GetWordContentByOpenXmlAdvanced()", ex.StackTrace?.ToString());return null;}
}/// <summary>
/// 高级内容提取,支持超链接等
/// </summary>
private static void ExtractBodyContentAdvanced(Body body, StringBuilder contentBuilder, bool includeHyperlinks)
{foreach (var element in body.Elements()){if (element is Paragraph paragraph){ExtractParagraphContentAdvanced(paragraph, contentBuilder, includeHyperlinks);contentBuilder.AppendLine();}else if (element is Table table){ExtractTableContentAdvanced(table, contentBuilder, includeHyperlinks);}else if (!(element is SectionProperties)){// 递归处理其他元素foreach (var childElement in element.Elements()){ExtractBodyContentAdvanced(new Body(childElement), contentBuilder, includeHyperlinks);}}}
}/// <summary>
/// 高级段落内容提取
/// </summary>
private static void ExtractParagraphContentAdvanced(Paragraph paragraph, StringBuilder contentBuilder, bool includeHyperlinks)
{foreach (var element in paragraph.Elements()){if (element is Run run){foreach (var text in run.Elements<Text>()){contentBuilder.Append(text.Text);}}else if (element is Hyperlink hyperlink && includeHyperlinks){foreach (var run2 in hyperlink.Elements<Run>()){foreach (var text in run2.Elements<Text>()){contentBuilder.Append(text.Text);}}}}
}/// <summary>
/// 高级表格内容提取
/// </summary>
private static void ExtractTableContentAdvanced(Table table, StringBuilder contentBuilder, bool includeHyperlinks)
{foreach (var row in table.Elements<TableRow>()){foreach (var cell in row.Elements<TableCell>()){foreach (var paragraph in cell.Elements<Paragraph>()){ExtractParagraphContentAdvanced(paragraph, contentBuilder, includeHyperlinks);}contentBuilder.Append("\t");}contentBuilder.AppendLine();}
}/// <summary>
/// 提取脚注内容
/// </summary>
private static void ExtractFootnotesContent(FootnotesPart footnotesPart, StringBuilder contentBuilder)
{if (footnotesPart.Footnotes != null){contentBuilder.AppendLine("\n--- 脚注 ---");foreach (var footnote in footnotesPart.Footnotes.Elements<Footnote>()){foreach (var paragraph in footnote.Elements<Paragraph>()){ExtractParagraphContent(paragraph, contentBuilder);contentBuilder.AppendLine();}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/91068.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/91068.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【SpringAI实战】ChatPDF实现RAG知识库

一、前言 二、实现效果 三、代码实现 3.1 后端代码 3.2 前端代码 一、前言 Spring AI详解&#xff1a;【Spring AI详解】开启Java生态的智能应用开发新时代(附不同功能的Spring AI实战项目)-CSDN博客 二、实现效果 实现一个非常火爆的个人知识库AI应用&#xff0c;ChatPDF…

Qt小组件 - 8 图片浏览器

一个自制的图片浏览器&#xff0c;如果不想安装qfluentwidgets&#xff0c; CommandBarView可以使用QWidgetQPushButton替代安装 qfluentwidgets pip install PySide6-Fluent-Widgets[full]代码示例 # coding: utf-8 from typing import Unionfrom PySide6.QtCore import Qt, Q…

R study notes[1]

文章目录introducing to Rreferencesintroducing to R R is an integrated suite involved data handling,storage facility,calculations on arrays,tools for data analysis and so on.running the command R in the terminal of OS can start R software.in R terminal ,to…

由于主库切换归档路径导致的 Oracle DG 无法同步问题的解决过程

由于主库切换归档路径导致的 Oracle DG 无法同步问题的解决过程 在上一篇文章中&#xff0c;由于 Oracle 数据库的归档日志空间耗尽导致客户端无法连接数据库。在解决的过程中临时修改了归档路径。后来通过修改参数db_recovery_file_dest_size的值解决了问题。 但该操作导致DG无…

密码学与加密货币:构建去中心化信任的技术基石与未来挑战

密码学是加密货币的技术基石&#xff0c;两者通过数学原理构建去中心化信任体系。以下从技术原理、应用场景及未来挑战三方面展开分析&#xff1a;一、密码学基础&#xff1a;加密货币的安全基石非对称加密体系公钥与私钥&#xff1a;基于椭圆曲线密码学&#xff08;ECC&#x…

用于 Web 认证的 抗量子签名——ML-DSA 草案

1. 引言 本文描述了在 Web Authentication (WebAuthn) 中实现无密码认证&#xff08;Passwordless authentication&#xff09;的方法&#xff0c;该方法使用模块格&#xff08;Module-Lattice&#xff09;为基础的数字签名标准&#xff08;ML-DSA&#xff09;&#xff0c;即 …

ubuntu18.04解压大的tar.gz文件失败

1. 问题描述 我在vmware的虚拟机装有petalinux环境&#xff0c;需要解压downloads_2020.2.tar.gz这个大的压缩包文件&#xff0c;但是总是失败&#xff0c;而且过程很漫长 tar: downloads/git2/github.com.vim.vim.git/objects/pack/pack-f7f2e2add0c8972a9141b557ef725c38069…

App拉起:唤醒即达,告别繁琐操作

在移动互联网进入存量竞争的今天&#xff0c;“让用户少点一次、少等一秒”往往意味着20%以上的转化率差异。openinstall把这套体验总结成一套可落地的App拉起方案&#xff1a;一套SDK一组链接跳转规则一个可自定义的落地页&#xff0c;就能把Web→App的整条动线缩成一次点击。…

开发指南125-HTML DOM事件

1、onload和onunload在页面或某个元素加载完成后或离开后触发事件。2、onchange用于在元素的值发生变化时触发事件。一般用于<input>, <select>, <textarea>等元素3、onfocus 和 onblur激活或失去焦点时触发4、onmouseover 和 onmouseout鼠标移入或移除时触发…

使用redis 作为消息队列时, 如何保证消息的可靠性

使用Redis作为消息队列时&#xff0c;如何保证消息的可靠性 在分布式系统中&#xff0c;消息队列扮演着不可或缺的角色&#xff0c;它能够有效地实现服务间的解耦和异步通信。Redis凭借其出色的性能&#xff0c;常常被用作轻量级的消息队列。然而&#xff0c;Redis本质上是一个…

CentOS7 安装和配置教程

CentOS7 安装和配置教程第一部分&#xff1a;安装准备1. 下载CentOS 7镜像2. 创建安装介质第二部分&#xff1a;安装步骤1. 在VMeare上安装CentOS-7-x86_64-Minimal2. 安装配置3. 安装过程第三部分&#xff1a;初始配置1. 首次启动设置2. 网络配置3. 防火墙配置第四部分&#x…

clock_getres系统调用及示例

39. clock_getres - 获取时钟精度 函数介绍 clock_getres系统调用用于获取指定时钟的精度&#xff08;分辨率&#xff09;。它返回时钟能够表示的最小时间间隔。 函数原型 #include <time.h>int clock_getres(clockid_t clk_id, struct timespec *res);功能 获取指定时钟…

MCU+RTOS调试

1. 引言在做项目时&#xff0c;百分之三十的时间写代码&#xff0c;还有百分之70的时间用于调试。本期将以Keil为例进行调试章节的讲解&#xff0c;目的在于做出一个标准化的调试步骤&#xff0c;方便大家学习如何调试代码。内容分为基础调试、中级调试及进阶调试三部分&#x…

Redis的数据淘汰策略是什么?有哪些?

1.监测设置了TTL的数据volatile-lru&#xff1a;淘汰最近最少使用的数据volatile-lfu&#xff1a;淘汰最近使用次数最少的数据volatile-ttl&#xff1b;淘汰将要过期的数据volatile-random&#xff1a;随机淘汰2.监测全库数据allkeys-lru&#xff1a;淘汰最近最少使用的数据all…

相控阵波束跃度指向误差Matlab仿真

波束跃度影响&#xff1a;TR芯片移相器位数、阵元数量、校准后阵元初始相位、TR芯片移相器精度、波控计算精度等。用MATLAB进行TR芯片移相器位数、阵元数量对指向误差进行仿真。 close all; %线阵波束跃度仿真 20250726 %beam displacement % 波束跃度影响&#xff1a;TR芯片移…

板凳-------Mysql cookbook学习 (十二--------6)

MySQL 8 导入二进制文件(trailer.ogv)操作指南 在MySQL中导入二进制文件(如trailer.ogv视频文件)通常有几种方法&#xff0c;我将详细介绍每种方法的操作步骤。 方法一&#xff1a;使用LOAD_FILE函数导入BLOB字段 这是最直接的方法&#xff0c;适合中小型二进制文件。sql - 1. …

昇思学习营-【模型推理和性能优化】学习心得_20250730

一、权重的加载 模型包含两部分&#xff1a; base model 和 LoRA adapter 其中base model的权重在微调时被冻结&#xff0c; 推理时加载原权重即可&#xff0c;LoRA adapter可通过PeftModel.from_pretrained进行加载。 二、启动推理 通过model.generate&#xff0c;启动推理…

[AI8051U入门第十一步]W5500-服务端

学习目标: 1、连接TCP/IP 2、学习W5500作为服务端代码一、TCP/IP介绍 TCP/IP 协议栈介绍 TCP/IP(Transmission Control Protocol / Internet Protocol)是互联网通信的核心协议族,定义了数据如何在网络中进行传输和路由。它由多个协议组成,采用分层架构,确保不同设备之间…

C 标准库 <time.h> 函数详解

目录 概述 1 核心数据类型 1.1 time_t 1.2 clock_t 1.3 struct tm 1.4 size_t 2 核心函数 2.1 时间获取函数 2.2 时间转换函数 2.3 时间差计算 2.4 时间格式化函数 3 线程安全版本&#xff08;POSIX 扩展&#xff09; 3.1 函数列表 3.2 时间处理完整示例 4 重要…

基于BEKK-GARCH模型的参数估计、最大似然估计以及参数标准误估计的MATLAB实现

基于BEKK-GARCH模型的参数估计、最大似然估计以及参数标准误估计的MATLAB实现。BEKK-GARCH模型是一种多变量GARCH模型&#xff0c;用于估计多个时间序列的条件方差和协方差矩阵。 MATLAB实现BEKK-GARCH模型 1. 准备数据 假设你已经有一个时间序列数据矩阵 returns&#xff0c;每…