npoi 实现类似excel、word自身的加密解密效果
最近在做一个文件管理系统,要求上传的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自身的加密解密效果的更多相关文章
- AES加密、解密(linux、window加密解密效果一致,支持中文)
转自: http://sunfish.iteye.com/blog/2169158 import java.io.UnsupportedEncodingException; import java.s ...
- NPOI - .NET Excel & Word操作组件
概要 NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. NPOI是构建在POI 3.x版本之上的,它可以在没有安装Offi ...
- word&excel&ppt文档加密方式
ppt excel word
- Npoi导入导出Excel操作
之前公司的一个物流商系统需要实现对订单的批量导入和导出,翻阅了一些资料,最后考虑使用NPOI实现这个需求. 在winform上面实现excel操作:http://www.cnblogs.com/Cal ...
- C# 使用 NPOI 库读写 Excel 文件
NPOI 是开源的 POI 项目的.NET版,可以用来读写Excel,Word,PPT文件.在处理Excel文件上,NPOI 可以同时兼容 xls 和 xlsx.官网提供了一份 Examples,给出 ...
- 如何在web中实现类似excel的表格控件
Execl功能非常强大,内置的很多函数或公式可以大大提高对数据的加工处理能力.那么在web中有没有类似的控件呢?经过一番搜寻,发现handsontable具备了基本的excel功能支持公式,同时能对数 ...
- NPOI导入导出EXCEL通用类,供参考,可直接使用在WinForm项目中
以下是NPOI导入导出EXCEL通用类,是在别人的代码上进行优化的,兼容xls与xlsx文件格式,供参考,可直接使用在WinForm项目中,由于XSSFWorkbook类型的Write方法限制,Wri ...
- .net利用NPOI导入导出Excel
NPOI在.net中的操作Excel 1.读取 using (FileStream stream = new FileStream(@"c:\客户资料.xls", FileMode ...
- Aspose 强大的服务器端 excel word ppt pdf 处理工具
Aspose 强大的服务器端 excel word ppt pdf 处理工具 http://www.aspose.com/java/word-component.aspx
随机推荐
- Linux记录-批量安装ssh(转载)
首先,需要检查expect是否安装:rpm -qa|grep expect 然后,在操作机上创建公钥:ssh-keygen 一路回车即可 创建好之后到/root/.ssh/下就可以看到id开头的2个文 ...
- 报错:org.apache.sqoop.common.SqoopException Message: CLIENT_0001:Server has returned exception NoClassDefFoundError: org/codehaus/jackson/map/JsonMappingException
报错背景: CDH集成sqoop2服务之后,创建好link和job之后,执行job的时候报错. 报错现象: sqoop:> start job -j Exception has occurred ...
- (转载)文献可视化--vosviewer入门
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/weixin_42613298/artic ...
- curl --resolve 查看证书情况
通过curl 解析证书 [root@harbor ~]# curl --resolve 'www.abc.com:127.0.0.1' https://www.abc.com/ -vvv * Cou ...
- 最新 博盾习言java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿. 博盾习言等10家互联网公司的校招Offer,因为某些自身原因最终选择了 博盾习言.6.7月主要是做系统复习.项目复盘.Le ...
- 第07组 Alpha冲刺(1/4)
队名:秃头小队 组长博客 作业博客 组长徐俊杰 过去两天完成的任务:完成人员分配,初步学习Android开发 Github签入记录 接下来的计划:继续完成Android开发的学习,带领团队进行前后端开 ...
- PHP mbstring通过多字节字符串扩展处理中文查找、计算问题
最近有个需求有到了mbstring相关的函数进行中文处理,如下: mb_strpos mb_strlen 过程中遇到一点比较奇怪的问题,及在本地环境运行没有问题 但我们生产环境是2台服务器,其中一台正 ...
- 设计模式之--Visitor
Ref: https://www.jianshu.com/p/feec47a25b67 https://www.cnblogs.com/alphablox/p/5346567.html
- Universial robot 运动学
1 正运动学: 1.1 DH方法理解 第i个坐标系固连在第i个连杆的左端.轴i固连于i-1杆,在i-1杆的右端. i坐标系固定在i杆上,随这i杆转动. 每个连杆有四个参数,第i个连杆: ai = ( ...
- 字段自动递增的数据库建表的SQL写法
数据库建表的SQL写法如下: 数据库建表的SQL写法如下: create table dataC( a int identity(1,2) primary key, b varchar(20)) ...