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
英文地址,請注明出處:http://en.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;每…