zoukankan      html  css  js  c++  java
  • 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("123");
    
                //保存并打开文档
                book.SaveToFile("d://test.xls", ExcelVersion.Version2013);  
    
    
    
    
    
         //解密
                //初始化一个Workbook实例
                Workbook workbook = new Workbook();
    
                //输入密码并加载文档
                workbook.OpenPassword = ("123");
                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 格式的加密解密)

      1   //此部分是加密的方法。
      2    #region 表格上传下载页的文件上传
      3    
      4    int SetFileSize = Convert.ToInt32(ConfigurationManager.AppSettings["SetFileSize"]);
      5    
      6    /// <summary>
      7      /// 文件上传 
      8      /// </summary>
      9     /// <returns></returns>
     10    public JsonResult UpLoadFile()
     11    {
     12        HttpFileCollectionBase file = Request.Files;
     13        string url = "";
     14    
     15        string fileName = "";//最终的文件名
     16        string Name = "";
     17        string FilePsd = "";//文件加密的密码
     18        string DepName = HttpUtility.UrlDecode(Request.QueryString["DepName"].Trim());
     19        string ProjectName = HttpUtility.UrlDecode(Request.QueryString["ProjectName"].Trim());
     20        string Updatetime = Request.QueryString["Updatetime"];
     21        string FormId = Request.QueryString["FormId"];
     22    
     23        if (Updatetime.Contains("中国标准时间"))
     24        {
     25            Updatetime = Updatetime.Trim().Replace("GMT 0800 (中国标准时间)", "");
     26        }
     27        else
     28        {
     29           Updatetime = Updatetime.Trim().Replace("GMT 0800 (China Standard Time)", "");
     30   
     31       }
     32       //中文:Wed Aug 07 2019 16:27:32 GMT+0800 (中国标准时间)
     33       //英文:Mon Sep 02 2019 09:11:01 GMT 0800 (China Standard Time)
     34       string FileName = HttpUtility.UrlDecode(Request.QueryString["FileName"].Trim());
     35   
     36       string fileType = "";
     37       TimeSpan span = DateTime.Now - Convert.ToDateTime(Updatetime);
     38       if (span.TotalHours > 24)
     39       {
     40           return Json(new { url = "", name = "-2" });//该文件在24小时内没有修改过不能上传
     41       }
     42       if (file.Count > 0)
     43       {
     44           if (file[0].ContentLength != 0)
     45           {
     46               Name = FileName;
     47               fileType = Name.ToString().Substring(Name.LastIndexOf("."));
     48               int length = Name.Length - fileType.Length;
     49               Name = Name.ToString().Substring(0, length);
     50               if (Name.Contains('.'))
     51               {
     52                   fileName = Name.ToString().Substring(0, length).Remove('.') + Encryption.GenerateRandomNumber(10);//表格名称+随机数;
     53               }
     54               else
     55               {
     56                   fileName = Name + Encryption.GenerateRandomNumber(10);//表格名称+随机数;
     57               }
     58               if (fileType != "*.xls" || fileType != "*.xlsx" || fileType != "*.pdf")
     59               {
     60                   //DailyForm/项目名称/部门名称/年/月/文件
     61                   string filePath = ConfigurationManager.AppSettings["DailyForm"] + "/" + ProjectName + "/" + DepName
     62                   + "/" + ComFunction.GetYear(DateTime.Now.ToString())
     63                     + "/" + ComFunction.GetMonth(DateTime.Now.ToString())
     64                    + "/" + fileName + fileType;
     65                   url = filePath;
     66                   if (!Directory.Exists(Server.MapPath(filePath)))
     67                   {
     68                       Directory.CreateDirectory(Server.MapPath(filePath).Substring(0, Server.MapPath(filePath).LastIndexOf('\')));
     69                   }
     70                   try
     71                   {
     72                       string savePath = Server.MapPath(filePath);
     73                       //把传入的原始文件存到文件夹。
     74                       file[0].SaveAs(savePath);
     75   
     76                       //判断该表格是否是敏感数据
     77                       string result = SQLHelper.GetFieldValue2("File", "t_able", "  and Id=@Id", new List<KeyValue> { new KeyValue { Key = "@Id", Value = FormId } });//是否是敏感的 0  不是  1 是
     78    
     79                           if (result != "1")
     80                           {
     81                               FilePsd = "0";
     82                           }
     83                           else  //需要加密文件
     84                           {
     85                               FilePsd = Encryption.GenerateRandomNumber(6);
     86    
     87                              
     88                            //====================================这里是加密主要的代码==================================
     89    
     90                               //如果类型是.docx  、 xlsx,直接加密  Nipo
     91                               if (fileType == ".docx" || fileType == ".xlsx")
     92                               {
     93                                   using (OfficeCryptoStream stream = OfficeCryptoStream.Open(@"" + savePath))
     94                                   {
     95                                       stream.Password = FilePsd;
     96                                       bool a = stream.Encrypted;
     97                                       stream.Save();
     98                                   }
     99                               }
    100                        //转换格式还未实现,搜了一些办法,都不适用。等以后做出来了来更新。
    101                               else  //如果是  *.xls; *.pdf;*.doc; *.rtf;先转换成 docx、xlsx、
    102                               {
    103                                   if (fileType == ".pdf")
    104                                    {
    105                                        //Workbook workbook1 = new Workbook();
    106                                        //workbook1.SaveCopyAs(savePath);
    107                                        //workbook1.Password = "123";
    108                                        //workbook1.SaveAs();
    109                                        //workbook1.Unprotect("123");
    110    
    111                                    }
    112                                }
    113    
    114    
    115                            }
    116    
    117    
    118    
    119    
    120                            //初始化一个工作簿并加载一个工作簿实例
    121                            //Workbook book = new Workbook();
    122                            //book.LoadFromFile(savePath);//"test.xls"
    123    
    124                            ////为工作簿设置访问密码
    125                            //book.Protect("147");
    126    
    127                            ////保存并打开文档
    128                            //book.SaveToFile(savePath, ExcelVersion.Version2013);
    129    
    130    
    131                            //   Workbook workbook = new Workbook();
    132                            //workbook.LoadFromFile(@"" + savePath);
    133                            //workbook.SaveToFile(savePath.Substring(0, savePath.Length-3)+ "xlsx", ExcelVersion.Version97to2003);//目标文件.xlsx
    134    
    135    
    136    
    137    
    138    
    139    
    140                            //正确
    141                            //doc、 可以,但是眉头 加了一行标志  docx没有被加密
    142                            //Document document = new Document();
    143                            //document.LoadFromFile(@"" + savePath);
    144                            //document.Encrypt("000");
    145                            //document.SaveToFile(savePath);
    146    
    147    
    148    
    149    
    150                            //初始化一个Document类实例并加载需要加密的Word文档
    151                            //Document doc = new Document(@"C:UsersAdministratorDesktopsample.docx");
    152                            //  Document doc = new Document(Server.MapPath(filePath));
    153                            //Document doc = new Document(@"D:32324.docx");
    154                            ////设置打开Word文档的密码
    155                            //doc.Encrypt("123");
    156                            ////保存并打开文档
    157                            //doc.SaveToFile( "sds.docx", FileFormat.Docx);
    158    
    159                            if (new FileInfo(Server.MapPath(filePath)).Length <= SetFileSize)//
    160                            {
    161                            }
    162                            else
    163                            {
    164                                //大于XM
    165                                System.IO.File.Delete(Server.MapPath(filePath));
    166                            }
    167    
    168                        }
    169                        catch (Exception ex)
    170                        {
    171                        }
    172                        Name = Name + fileType;
    173                    }
    174                    else
    175                    {
    176                        return Json(new { url = "", name = "-1" });//格式不合法
    177                    }
    178                }
    179            }
    180            url = System.Web.HttpUtility.UrlEncode(url);
    181            Name = System.Web.HttpUtility.UrlEncode(Name + "&" + FilePsd);
    182            return Json(new { url = url, name = Name });
    183        }
    184        #endregion

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

      1     /// <summary>
      2         /// 原文件下载和操作员上传的文件下载方法
      3         /// </summary>
      4         /// <param name="UploadDownloadId">上传下载ID</param>
      5         /// <param name="FilePath"></param>
      6         /// <param name="FormName"></param>
      7         /// <param name="type">0:下载提交的日常表格,1下载表格模板</param>
      8         /// <param name="type2">0: 上传下载页面,1审批页面</param>
      9         public void DownFile(string FilePath, string FormName, int UploadDownloadId, int type, int type2)
     10         {
     11             //判断是否有下载权限
     12             EnUser UserInfo = Session["UserInfo"] as EnUser;
     13 
     14             DateTime DownTime = DateTime.Now;
     15             EnUploadDownload UploadDownload = new EnUploadDownload();
     16             try
     17             {
     18                 string DownFormName = "";
     19                 string FileCompletePath = "";//原文件完整路径
     20                 string CopyFileCompletePath = "";//复制文件完整路径
     21                 string FilePsd = "";//文件密码
     22                 string NewPath = "";//生成临时新的文件。
     23                 bool ExistFile = false;
     24                 //下载输出 
     25                 if (type == 1)
     26                 {
     27                     DownFormName = "表格模板___" + FormName; 
     28                 }
     29                 else
     30                 {
     31                     DownFormName = FormName;
     32                     //先把文件解密存在新的文件夹下载完毕然后删掉
     33                     //根据UploadDownloadId 查找需不需要解密,0不需要,其他需要。 
     34                     FilePsd = SQLHelper.GetFieldValue2("FilePwd", "t_table", "  and Id=@Id", new List<KeyValue> { new KeyValue { Key = "@Id", Value = UploadDownloadId } });//是否需要解密的 0  不是  其他 是
     35                     if (FilePsd != "0" && FilePsd != "" && (FilePath.Contains(".pdf")!=true))//需要解密文件
     36                     {
     37                         ExistFile = ComFunction.ExistFilePath(FilePath);
     38                         if (ExistFile )  //如果文件存在并且文件不是pdf
     39                         { 
     40                             string[] arrry = FilePath.Split('/');
     41                             for (int i = 0; i < arrry.Length; i++)
     42                             {
     43                                 if (i > 1 && i != 7)
     44                                 {
     45                                     NewPath = NewPath + '/' + arrry[i];
     46                                 }
     47                             }
     48                             NewPath = ("~/DeclassifiedFile" + NewPath + '/' + Encryption.GenerateRandomNumber(4) + arrry[7]).Trim();
     49 
     50                             //路径不存在创建路径
     51                             if (!Directory.Exists(Server.MapPath(NewPath)))
     52                             {
     53                                 Directory.CreateDirectory(Server.MapPath(NewPath).Substring(0, Server.MapPath(NewPath).LastIndexOf('\')));
     54                             }
     55                             //获取完整路径
     56                             FileCompletePath = ComFunction.CompletePath(FilePath);
     57                             CopyFileCompletePath = ComFunction.CompletePath(NewPath);
     58 
     59                             //====================================这里是解密主要的代码==================================
     60 
     61                             //复制加密的文件到其他地址
     62                             FileInfo fi1 = new FileInfo(FileCompletePath);
     63                             FileInfo fi2 = new FileInfo(CopyFileCompletePath);
     64                             fi1.CopyTo(CopyFileCompletePath);
     65 
     66                             ////解密
     67                             using (OfficeCryptoStream stream = OfficeCryptoStream.Open(@"" + CopyFileCompletePath, FilePsd))
     68                             {
     69                                 stream.Password = null;
     70                                 bool b = stream.Encrypted;
     71                                 stream.Save();
     72                                 FilePath = NewPath;
     73                             }
     74                         }
     75                     }
     76                     else
     77                     {
     78 
     79                     }
     80                 }
     81                   //执行下载方法
     82                 string result = ComFunction.DownLoadFile(DownFormName, FilePath);
     83                 string remark = "";
     84                 if (FilePsd != "0")//需要解密文件
     85                 {
     86                     //删除零时被解密的文件
     87                     if (CopyFileCompletePath.Length > 1)
     88                     {
     89 
     90                         bool IsDelete = DeleteFile(CopyFileCompletePath);
     91 
     92                         if (!IsDelete)
     93                         {
     94                             string filePath = "~/Log/";
     95 
     96                             if (!Directory.Exists(Server.MapPath(filePath)))
     97                             {
     98                                 Directory.CreateDirectory(Server.MapPath(NewPath).Substring(0, Server.MapPath(filePath).LastIndexOf('\')));
     99                             }
    100                             LogHelper.OtherErroLogText2("下载文件时,备份文件没有被删除,文件路径:" + CopyFileCompletePath, ComFunction.CompletePath(filePath));
    101                         }
    102                     }
    103                 }
    104 
    105                 if (!result.Contains("-1"))
    106                 {
    107 
    108                     if (type2 == 0)
    109                     {
    110                         remark = "在上传下载页面";
    111                     }
    112                     else if (type2 == 1)
    113                     {
    114                         remark = "在审批页面";
    115                     }
    116                     else if (type2 == 3)
    117                     {
    118                         remark = "在审批记录页面";
    119 
    120                     }
    121                     else if (type2 == 4)
    122                     {
    123                         remark = "在日常表格列表查询页面";
    124 
    125                     }
    126                     else if (type2 == 5)
    127                     {
    128                         remark = "在打印页面";
    129 
    130                     }
    131                     else if (type2 == 6)
    132                     {
    133                         remark = "在打印模板详情页_表格";
    134 
    135                     }
    136 
    137                     else if (type2 == 7)
    138                     {
    139                         remark = "在打印模板详情页_附件";
    140 
    141                     }
    142 
    143 
    144 
    145                     remark = remark + (type == 0 ? "下载了提交的日常表格:" : "下载了表格模板:");
    146                     string optName = "下载";
    147                     if (type2 == 7 || type2 == 6)
    148                     {
    149                         optName = "打印__下载";
    150                     }
    151                     // 添加数据到上传下载表、表格操作记录表 
    152                     int count = BLL_FormOperationRecord.AddFormOperationRecord(UploadDownloadId, UserInfo.Id, DownTime, optName, remark + FormName); 
    153 
    154                     if (count > 0)
    155                     {
    156 
    157                     }
    158                     else
    159                     {
    160 
    161                         //添加失败
    162                         
    163                     }
    164 
    165                 }
    166                 else
    167                 { 
    168                 }
    169             }
    170 
    171 
    172 
    173             catch (Exception ex)
    174             {
    175 
    176                 //写入错误日志
    177                 LogHelper.WriteExceptionLogToText(ex);
    178             }
    179 
    180         }

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

  • 相关阅读:
    单片机多功能调试助手
    《划时代51单片机C语言全新教程》第十九章 网络通信 概览
    《划时代51单片机C语言全新教程》第十五章 按键计数器 概览
    《划时代51单片机C语言全新教程》第十七章 频率计 概览
    前后台程序框架实例2
    《划时代51单片机C语言全新教程》第二十一章 深入编程 概览
    《划时代51单片机C语言全新教程》第二十二章 界面开发 概览
    《划时代51单片机C语言全新教程》第十八章 USB通信 概览
    《划时代51单片机C语言全新教程》第二十章 深入接口 概览
    《划时代51单片机C语言全新教程》第十六章 交通灯 概览
  • 原文地址:https://www.cnblogs.com/xiangrikui94/p/11528725.html
Copyright © 2011-2022 走看看