C# 将 Word 转文本存储到数据库并进行管理

简介: C# 将 Word 转文本存储到数据库并进行管理

功能需求

将 WORD 文件的二进制信息存储到数据库里,即方便了统一管理文件,又可以实行权限控制效果,此外,将 WORD 文件转化为文本存储,可以进一步实现对已存储文件的全文检索。 在应用项目里,我们将实现如下需求:

1、上传WORD文件,获取二进制数据和文本数据。

2、将二进制数据和文本数据保存到数据表中。

3、查询需要的数据文件,可提供下载功能。

范例运行环境

操作系统: Windows Server 2019 DataCenter

操作系统上安装 Office Word 2016

数据库:Microsoft SQL Server 2016

.net版本: .netFramework4.7.1 或以上

开发工具:VS2019  C#

设计数据表

打开 Microsoft SQL Server 2016 查询分析器,执行如下代码创建表:

代码片断如下:

 
CREATE TABLE [dbo].[f_words](
  [cid] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
  [filename] [nvarchar](100) NOT NULL,
  [bfile] [image] NULL,
  [fcontent] [nvarchar](max) NULL,
  [sys_instime] [datetime] NULL,
 CONSTRAINT [PK_f_words] PRIMARY KEY CLUSTERED 
(
  [cid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
 
ALTER TABLE [dbo].[f_words] ADD  CONSTRAINT [DF_f_words_cid]  DEFAULT (newid()) FOR [cid]
GO

创建成功后,右击f_words表,点击设计,呈现视图如下:

如图字段CID为唯一标识;filename存储上传时获取的文件名;bfile存储Word文件的二进制数据;fcontent存储WORD文件的文本转化信息;sys_instime存储添加的时间。

关键代码

组件库引入

Word文件内容转文本

public string getWordTxt(string _filename,bool getHtmlContent) 方法,参数1 传入要读取的 WORD 文件路径,参数2 设定是否获取HTML格式的文本。

public string getWordTxt(string _filename,bool getHtmlContent)
        {
            resultReport = "";
            Object Nothing = System.Reflection.Missing.Value;
 
            object filename = _filename;
            //创建一个名为WordApp的组件对象
            DateTime beforetime = DateTime.Now;
            Word.Application WordApp = new Word.Application();
            //创建一个名为WordDoc的文档对象
            WordApp.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;
 
            Word.Document WordDoc = WordApp.Documents.Open(ref filename, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing);
 
            WordDoc.SpellingChecked = false;//关闭拼写检查
 
            WordDoc.ShowSpellingErrors = false;//关闭显示拼写错误提示框
 
            DateTime aftertime = DateTime.Now;
 
            string rv = WordDoc.Content.Text;
            Sys_Custom_DocVar = "";
            Sys_Custom_DocVar2 = "";
            foreach (Word.Variable ov in WordDoc.Variables)
            {
                if (ov.Name == "sys_custom_docvar")
                {
                    //                    WordDoc.Content.Text = ov.Value;
                    Sys_Custom_DocVar = ov.Value;
                } else if (ov.Name == "sys_custom_docvar2")
                {
                    //                    WordDoc.Content.Text = ov.Value;
                    Sys_Custom_DocVar2 = ov.Value;
                }
            }
            foreach (Word.ContentControl cc in WordDoc.ContentControls)
            {
                resultReport += cc.ID + ":" + cc.Tag + "<br>";
 
            }
            string _path = Path.GetDirectoryName(_filename) + "\\";
 
            object _expFile = _path + Guid.NewGuid().ToString() + ".html";
            if (getHtmlContent == true)
            {
                object   wsf = Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatHTML;
                WordDoc.SaveAs2(ref _expFile,ref wsf, ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing);
            }
            WordDoc.Close(ref Nothing, ref Nothing, ref Nothing);
      //关闭WordApp组件对象
      WordApp.Quit(ref Nothing, ref Nothing, ref Nothing);
 
      KillProcessByStartTime("WINWORD",beforetime,aftertime);
 
            if (File.Exists(_expFile.ToString()) == true)
            {
                FileEx fe = new FileEx();
                rv = fe.LoadFromFile(_expFile.ToString(), Encoding.Default);
                File.Delete(_expFile.ToString());
            }
            return rv;
    }
 
public string KillProcessByStartTime(string processName,DateTime beforetime,DateTime aftertime)
    {
      Process[] ps = Process.GetProcesses();
      foreach (Process p in ps)  
      {
        if(p.ProcessName.ToUpper()!=processName) continue;
        if(p.StartTime > beforetime && p.StartTime < aftertime)
        {
          try
          {
            p.Kill();
          }
          catch(Exception e)
          {
            return e.Message;
          }
        }
      }  
      return "";
    }

上传及保存举例

本示例是获取上传的文件并保存,将保存后的文件获取二进制及文本数据存储到数据库中。

示例代码如下:

string filename = Request.PhysicalApplicationPath + "\\app_data\\" + Guid.NewGuid().ToString() + ".docx";  //预生成文件名
//File1为上传控件
File1.PostedFile.SaveAs(filename);  //保存文件
 
//添加SQL参数,此处仅为示例
ArrayList paras = new ArrayList();
paras.Add(new SqlParameter("filename", filename));
paras.Add(new SqlParameter("fcontent", getWordTxt(filename,false)));  //word转文本
paras.Add(new SqlParameter("bfile", GetBinaryData(filename)));  //word的二进制信息
paras.Add(new SqlParameter("sys_instime", System.DateTime.Now));
 
File.Delete(filename);
 
//保存到数据表
ExecDbScripts("INSERT INTO [f_words]([filename],[bfile],[fcontent],[sys_instime])  VALUES(@filename, @bfile,@fcontent,@sys_instime)", paras);

得到文件Byte[]数据方法

public byte[] GetBinaryData(string filename)
{
  if(!File.Exists(filename))
  {
    return null;
  }
  FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
  byte[] imageData = new Byte[fs.Length];
  fs.Read( imageData, 0,Convert.ToInt32(fs.Length));
  fs.Close();
  return imageData;
}   

查询并下载Word文件

我们可以通过 select filename from f_words where fcontent like '%key%' 等语句形式进行查询结果,对于结果中的数据我们可以通过传递CID唯一标识参数,定位二进制信息进行下载,示例代码如下:

 
  string strConn =ConfigurationSettings.AppSettings["Connection"];
  SqlConnection Conn = new SqlConnection(strConn );
  SqlCommand Cmd = new SqlCommand();
 
  Cmd.Connection = Conn;
 
  SqlDataReader myDr;
 
  Cmd.CommandText = " select filename from f_words where  cid=@cid ";
   
 
  SqlParameter   para2=new   SqlParameter("@cid",SqlDbType.UniqueIdentifier);
  para2.Value=(new Guid(_cid));
  Cmd.Parameters.Add(para2);
  try
  {
             Conn.Open();
             myDr = Cmd.ExecuteReader();
             bool _hasrows=myDr.HasRows;
             if (myDr.Read())
           {
 
                 string extendname = "docx";
 
                 byte[] bytes = (byte[])myDr["bfile"];
                 
                 
                 Response.Buffer = true;
                 Response.Charset = "utf-8";
                 Response.AppendHeader("Content-Disposition", "inline;filename=" + HttpUtility.UrlEncode(myDr["filename"].ToString() + "" + extendname)); //把 attachment 改为 online 则在线打开
                 Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8");
                 Response.AppendHeader("Content-Length", bytes.Length.ToString());
                 Response.ContentType = "application/octet-stream"; 
                 
                     Page.EnableViewState = false;
                     Response.BinaryWrite(bytes);
                     Response.Flush();
       }
             myDr.Close();
         }
         catch (SqlException ex)
         {
         }
         finally
         {
             Conn.Close();
             Conn.Dispose();
         }
}

总结

上传保存到数据库的代码仅供参考,添加参数仅为抽象调用,需要自行实现数据操作代码。

下载大尺寸文件使用 Response.BinaryWrite() 方法可能会使浏览器无响应,可考虑使用 bytes.Length  判断如果尺寸较大的话,则生成文件到服务器并提供URL下载链接的方法。

这些代码我们提供了一些操作WORD及数据表的相关的关键方法,这里仅作参考,欢迎大家评论指教!

相关文章
|
3月前
|
自然语言处理 关系型数据库 MySQL
如何在mysql数据库里进行文本的相似度排序?
【8月更文挑战第28天】如何在mysql数据库里进行文本的相似度排序?
360 62
|
19天前
|
XML C# 开发工具
C# 删除Word文档中的段落
【11月更文挑战第3天】本文介绍了两种方法来操作 Word 文档:一是使用 `Microsoft.Office.Interop.Word` 库,适用于 Windows 环境下操作 Word 文档,需引用相应库并在代码中引入命名空间;二是使用 Open XML SDK,适用于处理 .docx 格式的文档,通过引用 `DocumentFormat.OpenXml` 库实现。文中提供了示例代码,展示了如何打开、删除段落并保存文档。
|
1月前
|
机器学习/深度学习 存储 自然语言处理
LangChain-22 Text Embedding 续接21节 文本切分后 对文本进行embedding向量化处理 后续可保存到向量数据库后进行检索 从而扩展大模型的能力
LangChain-22 Text Embedding 续接21节 文本切分后 对文本进行embedding向量化处理 后续可保存到向量数据库后进行检索 从而扩展大模型的能力
41 0
|
2月前
|
自然语言处理 关系型数据库 MySQL
match如何在mysql数据库里进行文本的相似度排序?
【9月更文挑战第1天】match如何在mysql数据库里进行文本的相似度排序?
112 1
|
3月前
|
数据库
C#Winform使用NPOI获取word中的数据
C#Winform使用NPOI获取word中的数据
182 2
|
4月前
|
SQL 自然语言处理 网络协议
【Linux开发实战指南】基于TCP、进程数据结构与SQL数据库:构建在线云词典系统(含注册、登录、查询、历史记录管理功能及源码分享)
TCP(Transmission Control Protocol)连接是互联网上最常用的一种面向连接、可靠的、基于字节流的传输层通信协议。建立TCP连接需要经过著名的“三次握手”过程: 1. SYN(同步序列编号):客户端发送一个SYN包给服务器,并进入SYN_SEND状态,等待服务器确认。 2. SYN-ACK:服务器收到SYN包后,回应一个SYN-ACK(SYN+ACKnowledgment)包,告诉客户端其接收到了请求,并同意建立连接,此时服务器进入SYN_RECV状态。 3. ACK(确认字符):客户端收到服务器的SYN-ACK包后,发送一个ACK包给服务器,确认收到了服务器的确
192 1
|
4月前
|
前端开发 数据库
文本----富文本数据如何存入到数据库当中,解决方法,看其他大佬写的文章
文本----富文本数据如何存入到数据库当中,解决方法,看其他大佬写的文章
文本----富文本数据如何存入到数据库当中,解决方法,看其他大佬写的文章
|
5月前
|
NoSQL Redis 数据库
docker-compose 自动管理 数据库
docker-compose 自动管理 数据库
146 3
|
4月前
|
存储 JavaScript 前端开发
文本,三步走构思,富文本点击提交能够存储到数据库当中(下),最快的方法,还是会看资料,因此会整合资料最好,直接看资料最快,因为是JWT的资料,我们要设置好登录的内容,看登录的地方怎样写的
文本,三步走构思,富文本点击提交能够存储到数据库当中(下),最快的方法,还是会看资料,因此会整合资料最好,直接看资料最快,因为是JWT的资料,我们要设置好登录的内容,看登录的地方怎样写的
|
6月前
|
存储 数据可视化 关系型数据库
【MySQL进阶之路 | 基础篇】创建和管理数据库
【MySQL进阶之路 | 基础篇】创建和管理数据库