最近在做一个文件管理系统,要求上传的excel、word、pdf 文件加密存在服务器上。在系统里下载可以不输密码直接打开,在服务器上点开文件必须要输密码。要考虑做好一劳永逸、也不能用收费的。以前没做过关于文档加密的东西,网上搜了好多, 可以实现加密解密的大致分为3种:

1:Spire

参考地址:https://zhidao.baidu.com/question/560428556.html

有免费的,我下载dll做完后发现有水印,因为公司的文件都是很正式的文件,所以果断放弃了它。这款能实现多种类型的文件加密解密,如果公司愿意花钱买,用这个还是很不错的。可以给我们开发人员省很多事。

使用步骤:免费版本可以在官网下载,然后把dll文件引入项目就可以使用了( Free Spire.Xls)。
以下几个网址介绍的很详细,
                   https://www.cnblogs.com/asxinyu/p/4346907.html
                  https://www.cnblogs.com/cjm123/p/8660810.html
上代码:

  using  添加引用。
//加密
//初始化一个工作簿并加载一个工作簿实例
Workbook book = new Workbook();
book.LoadFromFile("d://test.xls"); //为工作簿设置访问密码
book.Protect(""); //保存并打开文档
book.SaveToFile("d://test.xls", ExcelVersion.Version2013); //解密
//初始化一个Workbook实例
Workbook workbook = new Workbook(); //输入密码并加载文档
workbook.OpenPassword = ("");
workbook.LoadFromFile("d://test.xls", ExcelVersion.Version2013); //取消保护
workbook.UnProtect(); //保存
workbook.SaveToFile("d://test.xls", ExcelVersion.Version2013) //word加密
// savePath绝对路径
//doc 可以,但是眉头 加了一行水印 。docx没有被加密
//Document document = new Document();
//document.LoadFromFile(@"" + savePath);
//document.Encrypt("000");
//document.SaveToFile(savePath);

2:C# Office组件 dll word.dll excel.dll

没用这个原因是:

要保证机器本身安装了office.因为客户分布比较广, 不能保证每个用户电脑都安装了这个组件。所以没有用代码试。

3:NPOI

这个是免费的,但是我搜到的可以加密的格式并不多,但是由于系统中pdf 文件极少出现,我只需要操作xlsx、docx 格式的文件就好,所以还是 可以满足我的需求,就用了这个。在做的过程中只找到了如何用npio 加密,没有看到解密的。 只加密不能解密也不行啊,后来搜了好多还是没找到解决办法,灵机一动,把加密的参数赋为null, 下载下来的文件就直接打开了。终于在答应交东西日期之前把功能实现了。然后就想着记录一下给别人参考,别人在着急用的时候业务相同可以直接拿去用了 。 自己做了这几年的开发,每次都是搜别人的东西用,今天开始也记录些东西给别人提供方便。

看到有的文章说xls也可以实现,但是我在试 的过程中,并没有成功,不知道是不是dll 版本不一样导致。

介绍如何引用: https://blog.csdn.net/weixin_39029925/article/details/75389075
参考的文章:https://www.cnblogs.com/teamblog/p/6158140.html

上代码: mvc、uploadify文件插件。(以下代码只能保证实现 xlsx、docx 格式的加密解密)

   //此部分是加密的方法。
#region 表格上传下载页的文件上传 int SetFileSize = Convert.ToInt32(ConfigurationManager.AppSettings["SetFileSize"]); /// <summary>
/// 文件上传
/// </summary>
/// <returns></returns>
public JsonResult UpLoadFile()
{
HttpFileCollectionBase file = Request.Files;
string url = ""; string fileName = "";//最终的文件名
string Name = "";
string FilePsd = "";//文件加密的密码
string DepName = HttpUtility.UrlDecode(Request.QueryString["DepName"].Trim());
string ProjectName = HttpUtility.UrlDecode(Request.QueryString["ProjectName"].Trim());
string Updatetime = Request.QueryString["Updatetime"];
string FormId = Request.QueryString["FormId"]; if (Updatetime.Contains("中国标准时间"))
{
Updatetime = Updatetime.Trim().Replace("GMT 0800 (中国标准时间)", "");
}
else
{
Updatetime = Updatetime.Trim().Replace("GMT 0800 (China Standard Time)", ""); }
//中文:Wed Aug 07 2019 16:27:32 GMT+0800 (中国标准时间)
//英文:Mon Sep 02 2019 09:11:01 GMT 0800 (China Standard Time)
string FileName = HttpUtility.UrlDecode(Request.QueryString["FileName"].Trim()); string fileType = "";
TimeSpan span = DateTime.Now - Convert.ToDateTime(Updatetime);
if (span.TotalHours > )
{
return Json(new { url = "", name = "-2" });//该文件在24小时内没有修改过不能上传
}
if (file.Count > )
{
if (file[].ContentLength != )
{
Name = FileName;
fileType = Name.ToString().Substring(Name.LastIndexOf("."));
int length = Name.Length - fileType.Length;
Name = Name.ToString().Substring(, length);
if (Name.Contains('.'))
{
fileName = Name.ToString().Substring(, length).Remove('.') + Encryption.GenerateRandomNumber();//表格名称+随机数;
}
else
{
fileName = Name + Encryption.GenerateRandomNumber();//表格名称+随机数;
}
if (fileType != "*.xls" || fileType != "*.xlsx" || fileType != "*.pdf")
{
//DailyForm/项目名称/部门名称/年/月/文件
string filePath = ConfigurationManager.AppSettings["DailyForm"] + "/" + ProjectName + "/" + DepName
+ "/" + ComFunction.GetYear(DateTime.Now.ToString())
+ "/" + ComFunction.GetMonth(DateTime.Now.ToString())
+ "/" + fileName + fileType;
url = filePath;
if (!Directory.Exists(Server.MapPath(filePath)))
{
Directory.CreateDirectory(Server.MapPath(filePath).Substring(, Server.MapPath(filePath).LastIndexOf('\\')));
}
try
{
string savePath = Server.MapPath(filePath);
//把传入的原始文件存到文件夹。
file[].SaveAs(savePath); //判断该表格是否是敏感数据
string result = SQLHelper.GetFieldValue2("File", "t_able", " and Id=@Id", new List<KeyValue> { new KeyValue { Key = "@Id", Value = FormId } });//是否是敏感的 0 不是 1 是 if (result != "")
{
FilePsd = "";
}
else //需要加密文件
{
FilePsd = Encryption.GenerateRandomNumber(); //====================================这里是加密主要的代码================================== //如果类型是.docx 、 xlsx,直接加密 Nipo
if (fileType == ".docx" || fileType == ".xlsx")
{
using (OfficeCryptoStream stream = OfficeCryptoStream.Open(@"" + savePath))
{
stream.Password = FilePsd;
bool a = stream.Encrypted;
stream.Save();
}
}
//转换格式还未实现,搜了一些办法,都不适用。等以后做出来了来更新。
else //如果是 *.xls; *.pdf;*.doc; *.rtf;先转换成 docx、xlsx、
{
if (fileType == ".pdf")
{
//Workbook workbook1 = new Workbook();
//workbook1.SaveCopyAs(savePath);
//workbook1.Password = "123";
//workbook1.SaveAs();
//workbook1.Unprotect("123"); }
} } //初始化一个工作簿并加载一个工作簿实例
//Workbook book = new Workbook();
//book.LoadFromFile(savePath);//"test.xls" ////为工作簿设置访问密码
//book.Protect("147"); ////保存并打开文档
//book.SaveToFile(savePath, ExcelVersion.Version2013); // Workbook workbook = new Workbook();
//workbook.LoadFromFile(@"" + savePath);
//workbook.SaveToFile(savePath.Substring(0, savePath.Length-3)+ "xlsx", ExcelVersion.Version97to2003);//目标文件.xlsx //正确
//doc、 可以,但是眉头 加了一行标志 docx没有被加密
//Document document = new Document();
//document.LoadFromFile(@"" + savePath);
//document.Encrypt("000");
//document.SaveToFile(savePath); //初始化一个Document类实例并加载需要加密的Word文档
//Document doc = new Document(@"C:\Users\Administrator\Desktop\sample.docx");
// Document doc = new Document(Server.MapPath(filePath));
//Document doc = new Document(@"D:\32324.docx");
////设置打开Word文档的密码
//doc.Encrypt("123");
////保存并打开文档
//doc.SaveToFile( "sds.docx", FileFormat.Docx); if (new FileInfo(Server.MapPath(filePath)).Length <= SetFileSize)//
{
}
else
{
//大于XM
System.IO.File.Delete(Server.MapPath(filePath));
} }
catch (Exception ex)
{
}
Name = Name + fileType;
}
else
{
return Json(new { url = "", name = "-1" });//格式不合法
}
}
}
url = System.Web.HttpUtility.UrlEncode(url);
Name = System.Web.HttpUtility.UrlEncode(Name + "&" + FilePsd);
return Json(new { url = url, name = Name });
}
#endregion

此部分是解密的方法,大致思路是:获取到要下载的文件路径,复制文件(a)到另一个文件夹(b),把b的文件解密保存,去下载b 的文件。因为有服务在监控a文件夹 的文件,会把他复制到另一个服务器。后台用代码把文件复制一份再解密后下载解密的文件。 这样能保证原始文件密码始终存在,服务监控复制文件不会把解密的文件一起复制走了。

     /// <summary>
/// 原文件下载和操作员上传的文件下载方法
/// </summary>
/// <param name="UploadDownloadId">上传下载ID</param>
/// <param name="FilePath"></param>
/// <param name="FormName"></param>
/// <param name="type">0:下载提交的日常表格,1下载表格模板</param>
/// <param name="type2">0: 上传下载页面,1审批页面</param>
public void DownFile(string FilePath, string FormName, int UploadDownloadId, int type, int type2)
{
//判断是否有下载权限
EnUser UserInfo = Session["UserInfo"] as EnUser; DateTime DownTime = DateTime.Now;
EnUploadDownload UploadDownload = new EnUploadDownload();
try
{
string DownFormName = "";
string FileCompletePath = "";//原文件完整路径
string CopyFileCompletePath = "";//复制文件完整路径
string FilePsd = "";//文件密码
string NewPath = "";//生成临时新的文件。
bool ExistFile = false;
//下载输出
if (type == )
{
DownFormName = "表格模板___" + FormName;
}
else
{
DownFormName = FormName;
//先把文件解密存在新的文件夹下载完毕然后删掉
//根据UploadDownloadId 查找需不需要解密,0不需要,其他需要。
FilePsd = SQLHelper.GetFieldValue2("FilePwd", "t_table", " and Id=@Id", new List<KeyValue> { new KeyValue { Key = "@Id", Value = UploadDownloadId } });//是否需要解密的 0 不是 其他 是
if (FilePsd != "" && FilePsd != "" && (FilePath.Contains(".pdf")!=true))//需要解密文件
{
ExistFile = ComFunction.ExistFilePath(FilePath);
if (ExistFile ) //如果文件存在并且文件不是pdf
{
string[] arrry = FilePath.Split('/');
for (int i = ; i < arrry.Length; i++)
{
if (i > && i != )
{
NewPath = NewPath + '/' + arrry[i];
}
}
NewPath = ("~/DeclassifiedFile" + NewPath + '/' + Encryption.GenerateRandomNumber() + arrry[]).Trim(); //路径不存在创建路径
if (!Directory.Exists(Server.MapPath(NewPath)))
{
Directory.CreateDirectory(Server.MapPath(NewPath).Substring(, Server.MapPath(NewPath).LastIndexOf('\\')));
}
//获取完整路径
FileCompletePath = ComFunction.CompletePath(FilePath);
CopyFileCompletePath = ComFunction.CompletePath(NewPath); //====================================这里是解密主要的代码================================== //复制加密的文件到其他地址
FileInfo fi1 = new FileInfo(FileCompletePath);
FileInfo fi2 = new FileInfo(CopyFileCompletePath);
fi1.CopyTo(CopyFileCompletePath); ////解密
using (OfficeCryptoStream stream = OfficeCryptoStream.Open(@"" + CopyFileCompletePath, FilePsd))
{
stream.Password = null;
bool b = stream.Encrypted;
stream.Save();
FilePath = NewPath;
}
}
}
else
{ }
}
//执行下载方法
string result = ComFunction.DownLoadFile(DownFormName, FilePath);
string remark = "";
if (FilePsd != "")//需要解密文件
{
//删除零时被解密的文件
if (CopyFileCompletePath.Length > )
{ bool IsDelete = DeleteFile(CopyFileCompletePath); if (!IsDelete)
{
string filePath = "~/Log/"; if (!Directory.Exists(Server.MapPath(filePath)))
{
Directory.CreateDirectory(Server.MapPath(NewPath).Substring(, Server.MapPath(filePath).LastIndexOf('\\')));
}
LogHelper.OtherErroLogText2("下载文件时,备份文件没有被删除,文件路径:" + CopyFileCompletePath, ComFunction.CompletePath(filePath));
}
}
} if (!result.Contains("-1"))
{ if (type2 == )
{
remark = "在上传下载页面";
}
else if (type2 == )
{
remark = "在审批页面";
}
else if (type2 == )
{
remark = "在审批记录页面"; }
else if (type2 == )
{
remark = "在日常表格列表查询页面"; }
else if (type2 == )
{
remark = "在打印页面"; }
else if (type2 == )
{
remark = "在打印模板详情页_表格"; } else if (type2 == )
{
remark = "在打印模板详情页_附件"; } remark = remark + (type == ? "下载了提交的日常表格:" : "下载了表格模板:");
string optName = "下载";
if (type2 == || type2 == )
{
optName = "打印__下载";
}
// 添加数据到上传下载表、表格操作记录表
int count = BLL_FormOperationRecord.AddFormOperationRecord(UploadDownloadId, UserInfo.Id, DownTime, optName, remark + FormName); if (count > )
{ }
else
{ //添加失败 } }
else
{
}
} catch (Exception ex)
{ //写入错误日志
LogHelper.WriteExceptionLogToText(ex);
} }

第一次写文章,由于不熟悉这个编辑器,重来了好多遍。 条理可能不太清晰,以后写多了应该逻辑思维就会好点。感谢提供参考文章的大佬们。

npoi 实现类似excel、word自身的加密解密效果的更多相关文章

  1. AES加密、解密(linux、window加密解密效果一致,支持中文)

    转自: http://sunfish.iteye.com/blog/2169158 import java.io.UnsupportedEncodingException; import java.s ...

  2. NPOI - .NET Excel & Word操作组件

    概要 NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. NPOI是构建在POI 3.x版本之上的,它可以在没有安装Offi ...

  3. word&excel&ppt文档加密方式

    ppt excel word

  4. Npoi导入导出Excel操作

    之前公司的一个物流商系统需要实现对订单的批量导入和导出,翻阅了一些资料,最后考虑使用NPOI实现这个需求. 在winform上面实现excel操作:http://www.cnblogs.com/Cal ...

  5. C# 使用 NPOI 库读写 Excel 文件

    NPOI 是开源的 POI 项目的.NET版,可以用来读写Excel,Word,PPT文件.在处理Excel文件上,NPOI 可以同时兼容 xls 和 xlsx.官网提供了一份 Examples,给出 ...

  6. 如何在web中实现类似excel的表格控件

    Execl功能非常强大,内置的很多函数或公式可以大大提高对数据的加工处理能力.那么在web中有没有类似的控件呢?经过一番搜寻,发现handsontable具备了基本的excel功能支持公式,同时能对数 ...

  7. NPOI导入导出EXCEL通用类,供参考,可直接使用在WinForm项目中

    以下是NPOI导入导出EXCEL通用类,是在别人的代码上进行优化的,兼容xls与xlsx文件格式,供参考,可直接使用在WinForm项目中,由于XSSFWorkbook类型的Write方法限制,Wri ...

  8. .net利用NPOI导入导出Excel

    NPOI在.net中的操作Excel 1.读取 using (FileStream stream = new FileStream(@"c:\客户资料.xls", FileMode ...

  9. Aspose 强大的服务器端 excel word ppt pdf 处理工具

    Aspose 强大的服务器端 excel word ppt pdf 处理工具 http://www.aspose.com/java/word-component.aspx

随机推荐

  1. (?:pattern) 与 (?=pattern)的区别

    共同点 (?:pattern) 与 (?=pattern)都匹配pattern,但不会把pattern结果放到Matches的集合中. 区别 (?:pattern) 匹配得到的结果包含pattern. ...

  2. 静态站点生成器-html-markdown-hugo

    推荐指数:

  3. 原生JavaScript判断浏览器对CSS属性是否支持

    /*判断浏览器是否支持某个css属性*/ function SupportCss(attrName){ var i=0, arr = SupportCss.opt.aBrowser, eleStyle ...

  4. jira7.3.6 windows7下安装、中文及破解

    一.事前准备 1:JDK下载并安装:jdk-6u45-windows-i586.exe 2:MySQL JDBC连接驱动:mysql-connector-java-5.1.25.zip 3:MySQL ...

  5. win10卸载office2010的工具

    本来想装一个高版本的office,于是想先卸载老版本的.结果在win10的应用和功能中,愣是没找到安装的office2010,使用360也找不到,没法卸载. 网上搜了一下,找到一个好工具,micros ...

  6. 剑指offer27:按字典序打印出该字符串中字符的所有排列

    1 题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入描述: ...

  7. scrapy框架4——下载中间件的使用

    一.下载中间件 下载中间件是scrapy提供用于用于在爬虫过程中可修改Request和Response,用于扩展scrapy的功能:比如: 可以在请求被Download之前,请求头部加上某些信息(例如 ...

  8. find_element_by_xpath()的几种方法

    Xpath (XML Path Language),是W3C定义的用来在XML文档中选择节点的语言一:从根目录/开始有点像Linux的文件查看,/代表根目录,一级一级的查找,直接子节点,相当于css_ ...

  9. net namespace实验

    Net namespace实验 在 Linux 中,网络名字空间可以被认为是隔离的拥有单独网络栈(网卡.路由转发表.iptables)的环境.网络名字空间经常用来隔离网络设备和服务,只有拥有同样网络名 ...

  10. IdentityServer4 手动验签及日志记录

    IdentityServer4的基础知识和使用方式网上有很多特别优秀的文章,如果有对其不了解的推荐阅读一下下面的两篇文章 http://www.ruanyifeng.com/blog/2014/05/ ...