zoukankan      html  css  js  c++  java
  • .net core excel导入导出

          做的上一个项目用的是vs2013,传统的 Mvc模式开发的,excel报表的导入导出都是那几段代码,已经习惯了。

    导入:
    string
    filename = ExcelFileUpload.FileName;//获取Execle文件名 string savePath = Server.MapPath(("UploadExcel\") + filename);//Server.MapPath 服务器上的指定虚拟路径相对应的物理文件路径 //savePath ="D:vsprojectProjectsexceltestwebexceltestwebuploadfiles est.xls" //Response.Write(savePath); DataTable ds = new DataTable(); ExcelFileUpload.SaveAs(savePath);//将文件保存到指定路径 DataTable dt = GetExcelDatatable(savePath);//读取excel数据 List<RegNumInfo> regList = ConvertDtToInfo(dt);//将datatable转为list File.Delete(savePath);//删除文件 Response.Write("<script>alert('上传文件读取数据成功!');</script>");
    导出:

       HSSFWorkbook workbook = new HSSFWorkbook();//创建一个excel文件
       ISheet sheet = workbook.CreateSheet("sheet1");//创建一个sheet
       IRow row = null;//设置行
       ICell cell = null;//设置单元格

       //创建第一行
       row = sheet.CreateRow(0);
       //创建第一列
      cell = row.CreateCell(0);
      //给第一列赋值
      cell.SetCellValue("类型");
      //创建第二列
      cell = row.CreateCell(1);
      //给第二列赋值
      cell.SetCellValue("数量");

       for (int i = 0; i < listHouse.Count; i++)
       {
        row = sheet.CreateRow(i+1);//第几行
        row.CreateCell(0).SetCellValue(listHouse[i].ParameterName);//第一个单元格
        row.CreateCell(1).SetCellValue(listHouse[i].Count);//第二个单元格
        // soure和count要和前台对应file
        //var housepa = new { soure = listHouse[i].ParameterName, count = listHouse[i].Count };
        //list.Add(housepa);
       }  

        MemoryStream ms = new MemoryStream();//声明一个内存流
       workbook.Write(ms);//将文件写入流中
       context.Response.ContentType = "application/vnd.ms-excel";//输入的格式
       //文件信息(文件头)attachment设置文件为打开 保存对话框
       context.Response.AddHeader("Content-Disposition",
      "attachment;filename=" + HttpUtility.UrlEncode(type, System.Text.Encoding.UTF8) +
       DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ".xls");
       context.Response.BinaryWrite(ms.ToArray());//字节格式输入
       context.Response.End();
       workbook = null;
       ms.Close();//关闭流
       ms.Dispose();//释放资源



        但是现在做项目我用的是vs2019 ,用.net core 2.2 开发。在做导入导出报表的时候发现以前的模式不好使了,原因是指定路径的方法不能用了:Server.MapPath(),

    用.net core 模式开发项目,也是刚接触怎末导入导出也不知道,那就只能问百度了。然后搜了一下,复制粘贴,修修改改很快就搞定了。

          在core里要注册IHostingEnvironment 环境变量才能做excel的导入导出操作,(这里之说简单操作,如何封装就看个人了)

         新建一个控制器,在控制器里直接注册就行了。

        

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using SmartNet.Core;
    using System.Data;
    using Microsoft.AspNetCore.Http.Abstractions;
    using Microsoft.AspNetCore.Mvc.ViewFeatures;
    using System.IO;
    using Newtonsoft.Json;
    using SmartNet.Data;
    using Microsoft.AspNetCore.Hosting;
    using OfficeOpenXml;
    using Microsoft.Azure.ActiveDirectory.GraphClient;
    
    namespace SmartNet.Web.Areas.ProjectManage.Controllers
    {
        public class TaskController : ControllerBase
        {
     private IHostingEnvironment _hostingEnvironment;
            public TaskController(IHostingEnvironment hostingEnvironment)
            {
                _hostingEnvironment = hostingEnvironment;
            }
        }
    }

       在做之前要下载插件:

    装完插件后,首先是导入操作:

      页面:  

    <div id="importBox" style="display:none">
        <form enctype="multipart/form-data" method="post" action="/####/####/Import">
            <input type="file" name="excelfile" />
            <input type="submit" value="导入" />
        </form>
    </div>
    <script>
     function TaiZhangExport() {
                        layer.open({
                            type: 1,
                            skin: 'layui-layer-rim', //加上边框
                            area: ['420px', '240px'], //宽高
                            content: $("#importBox").html()
                        });
                    }
    </script>
    

     后台:

       

    /// <summary>
    /// 公用路径
    /// </summary>
    /// <returns></returns>
    private Tuple<string, string> GetTuple(string ExcelName)
    {
    string sWebRootFolder = _hostingEnvironment.WebRootPath;//获取根路径,core资源文件夹一般都在www.root目录下,关于这块可以看我的 .net app接口文章,那里详细介绍了这块。
    string sFileName = $"{ExcelName}.xlsx";
    return Tuple.Create(sWebRootFolder, sFileName);
    }
    
    [HttpPost]
            public IActionResult Import(IFormFile excelfile)
            {
                string sWebRootFolder = GetTuple("报表模板").Item1;
                string sFileName = GetTuple("报表模板").Item2;
                FileInfo file = new FileInfo(Path.Combine(sWebRootFolder, sFileName));
                string[] FileType = excelfile.FileName.Split('.');
                if (FileType[1] != "xlsx" && FileType[1] != "xls")
                {
                    ///financemanage/ledger/list
                    return Content("你导如的文件格式不正确,请导入excel文件格式(.xlsx,xls)");
                }
    
                if (!System.IO.Directory.Exists(sWebRootFolder + sFileName))//判断路径是否存在
                {
                    file.Delete(); //删除服务器上的临时文件
                }
                try
                {
                    //FileStream对象表示在磁盘或网络路径上指向文件的流。这个类提供了在文件中读写字节的方。
                    //Create:文件存在删除该文件,不存在创建新文件。
                    using (FileStream fs = new FileStream(file.ToString(), FileMode.Create))
                    {
                        excelfile.CopyTo(fs);
                        fs.Flush();
                    }
                    using (ExcelPackage package = new ExcelPackage(file))
                    {
                        StringBuilder sb = new StringBuilder();
                        ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
                        int rowCount = worksheet.Dimension.Rows;
                        int ColCount = worksheet.Dimension.Columns;
                        bool isTrue = false;
                       //////////////////////////////////////////////////////////////////////////////////////
                      //注意在导入报表时,并不是能将导入就万事大吉了,要判断一下excel表里的数据是否和你要求的数据匹配,例如:时间数据,整型数据,浮点型数据,excel表中的每一列数据类型都要与你要求的每一列数据里类型匹配。
                     // 这时就需要我们自己在读取excel表中的数据时,自己去一个一个审查了。审查一般也有两种方式:
                       // 1,表中数据哪一行数据不通过,就过滤掉不通过的数据,通过的数据还按原方式导入,不通过的输出第几行,第几列的错误信息,比如:第二行,第三列,时间格式错误!(可以边判断边导入,一行通过就导入一行)
                      //  2,表中数据只要有一行不通过,整个表中的数据都不能导入,不通过的输出第几行,第几列的错误信息,比如:第二行,第三列,时间格式错误!(先判断后导入,就是先对整个表数据进行匹配,只要都通过了,才能导入)                     我在这里做的事第二种方式,至于选哪种方式要根据业务情况的。下面就是如何匹配数据了。
                       //  比如我要导入的数据有四行,第一行时string,第二行是:int  第三行是:float 第四行是:datatime  格式是(2019/10/23) 注意:时间格式要尽量定一个统一模式 
    
                        for (int row = 2; row <= rowCount; row++)//在excel表中第一行是标题,所以数据是从第二行开始的。
                        {
                            for (int col = 1; col <= ColCount; col++)
                            {
                                if (col>1&&col<4)
                                {
                                    if (worksheet.Cells[row, col].Value.ToString().Length == 0)//表中数据有可能是空,如果是字符格式就无所谓了,但是如果是整型或者浮点型,那就要判一下,给个默认值0了
                                    {
                                        worksheet.Cells[row, col].Value = 0;
                                    }
                                    if (!Regex.IsMatch(worksheet.Cells[row, col].Value.ToString(), @"^[+-]?d*[.]?d*$"))//大家知道,整型可以转浮点型,例如:float a  可以 a=1.0 也可以  a=1所以两个一块直接判断了。
                                    {
                                        if (isTrue == false)
                                        {
                                            sb.Append("导入文件失败!" + "	");
                                            sb.Append("        有一下错误:" + "	");
                                        }
                                        sb.Append("" + row + "" + col + "列数据类型错误!" + "	");
                                        isTrue = true;
                                    }
                                }
                                // Regex reg = new Regex(@"^(0[1-9]|1[0-2])/(0[1-9]|[12][0-9]|30|31)/([1-9]d{3})$", RegexOptions.None | RegexOptions.IgnoreCase | RegexOptions.Multiline);
                                // MatchCollection mc = reg.Matches(worksheet.Cells[row, col].Value.ToString());
                                //^(?d{2,4})/(?d{1,2})/(?d{1,2})$
                                if (col ==4)
                                {
                                    if (SelectDateTime(worksheet.Cells[row, col].Value.ToString()))//判断时间格式在SelectDatatime方法中处理的,在下面
                                    {
                                        if (isTrue == false)
                                        {
                                            sb.Append("导入文件失败!" + "	");
                                            sb.Append("        有一下错误:" + "	");
                                        }
                                        sb.Append("" + row + "" + col + "列时间格式类型错误!" + "	");
                                        isTrue = true;
                                    }
                                }
                            }
                            sb.Append(Environment.NewLine);//重新起一行
                        }
                        if (isTrue == true)
                        {
                            return Content(sb.ToString());   //如果isture==true 说明有错误数据就直接返回错误数据,就不再进行导入操作了。
                        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                       下面是,如果所有数据都匹配成功了,那就要执行导入操作了。
                     for (int row = 2; row <= rowCount; row++)
                        {
                          string 第一个数据=worksheet.Cells[Row,1].Value.ToString(),
                           int 第二个数据 = int.Parse(worksheet.Cells[Row,2].value.ToString()),
                           int 第三个数据 =float.Parse(worksheet.Cells[Row,3].value.ToString()),
                           string 第四个数据 =worksheet.Cells[Row,4].value.ToString(),
                           //下面就是如何把excel表中的数据插入数据库了,两种方式:1,数据一行一行插入。2,将数据存入DadaTable中整体存入。具体要看数据量了。
                         例如一行一行插入可以直接在for循环中直接插入就行了。
                             --插入的sql语句
                             --存储过程名
    
                            
                        }
                        file.Delete();//删除刚创建的临时文件。
                        return Redirect("/ReportManage/Finance_CostNoTower/List");
                    }
                }
                catch (Exception ex)
                {
                    return Content(ex.Message);
                }
            }
    public bool SelectDateTime(string strtime)
    {
    try
    {
    DateTime.Parse(strtime);//笼统的判断字符串格式是否是时间格式 
    }
    catch
    {
    return true;
    }
    string StrTime = strtime;
    //判断系统读取的时间格式是否和文件中的时间格式一致
    //例如文件上时间格式是"2019/07"而系统读取格式是:"2019/07/01 星期一 0:00:00"
    if (strtime.Length > 7)
    {
    //如果不一致,取第一个空格前的字符串。
    StrTime = strtime.Substring(0, strtime.IndexOf(' '));
    }
    //系统定义excel文件中时间格式是"2019/07"或者"2019/7"如果是其它格式则认为是错误时间格式。
    if (!StrTime.Contains('/'))
    {
    return true;
    }
    return false;
    
    }
    
    
     

    导入的基本过程也就这些了。下面是导出,导出就相对容易多了,不需要在进行数据匹配了。

        页面:

                    <button class="layui-btn" style="position: absolute;right: 20px;top: 60%;
                                    margin-top: -9px;cursor: pointer" onclick="Import()">
                        导出数据
                    </button>
    <script>
         
                    function Import() {
                        location.href = "/ReportManage/Finance_CostNoTower/Export?" +传入的参数
                    }
    </script>
    

      后台:

      public IActionResult Export()
            {
                
                DataTable dtList=获取数据库数据的方法(参数);
                string sWebRootFolder = GetTuple("报表模板").Item1;
                string sFileName = GetTuple("报表模板").Item2;
                FileInfo file = new FileInfo(Path.Combine(sWebRootFolder, sFileName));//创建一个FileInfo实例,创建路径
                if (!System.IO.Directory.Exists(sWebRootFolder + sFileName))//文件是否存在如果存在删掉文件重新创建。
                {
                    file.Delete(); //删除服务器上的临时文件
                }
                using (ExcelPackage package = new ExcelPackage(file))//创建excel
                {
                    // 添加worksheet
                    ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("aspnetcore");
                    //worksheet.Cells.Style.ShrinkToFit = true;//单元格自动适应大小
                    for (int i = 1; i < 4; i++)
                    {
                        worksheet.Column(i).Width = 25;//设置列宽
                    }
                    //添加头
                    worksheet.Cells[1, 1].Value = "excel表格第一列标题";
                    worksheet.Cells[1, 2].Value = "excel表格第二列标题";
                    worksheet.Cells[1, 3].Value = "excel表格第三列标题";
                    worksheet.Cells[1, 4].Value = "excel表格第四列标题";
                   if (dtList != null && dtList.Rows.Count > 0)
                    {
                        //添加值
                        int Count = 1;
                        for (int i = 0; i < dtList.Rows.Count; i++)
                        {
                            Count++;
                            DataRow item = dtList.Rows[i];//创建行                   
                            worksheet.Cells[Count, 1].Value = item[数据库中数据参数名].ToString();
                            worksheet.Cells[Count, 2].Value = item[数据库中数据参数名].ToString();
                            worksheet.Cells[Count, 3].Value = item[数据库中数据参数名].ToString();
                            worksheet.Cells[Count, 4].Value = item[数据库中数据参数名].ToString();
                          
                        }
    
                    }
                    package.Save();//保存
                }
    
                return File(sFileName, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "导出数据.xlsx");//导出excel表格
            }

        好了,到这里excel报表的导入导出就介绍完了。希望对一些朋友有些帮助。

          

      

     

       

      

          

        

  • 相关阅读:
    转:详解iPhone Tableview分批显示数据 点击加载更多
    能不写全局变量就不写全局变量。
    ios 打电话 一键拨号
    下一步目标:整理出1套相对成熟的ios 开发框架
    dispatch_sync 线程 GCD iOS
    iOS 播放声音 最简单的方法
    判断 网络是否通常,以及判断用户使用的网络类型,时2G\3G\还是wifi
    ios 特效 新思路 :加载gif 动画,然后在动画上增加点击事件即可。
    Oracle小技巧
    excel导出时”内存或磁盘空间不足“错误的解决方法
  • 原文地址:https://www.cnblogs.com/zpy1993-09/p/11726140.html
Copyright © 2011-2022 走看看