.net core excel导入导出
做的上一个项目用的是vs2013,传统的 Mvc模式开发的,excel报表的导入导出都是那几段代码,已经习惯了。
导入:
string filename = ExcelFileUpload.FileName;//获取Execle文件名
string savePath = Server.MapPath(("UploadExcel\\") + filename);//Server.MapPath 服务器上的指定虚拟路径相对应的物理文件路径
//savePath ="D:\vsproject\Projects\exceltestweb\exceltestweb\uploadfiles\test.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[] != "xlsx" && FileType[] != "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[];
int rowCount = worksheet.Dimension.Rows;
int ColCount = worksheet.Dimension.Columns;
bool isTrue = false;
//////////////////////////////////////////////////////////////////////////////////////
//注意在导入报表时,并不是能将导入就万事大吉了,要判断一下excel表里的数据是否和你要求的数据匹配,例如:时间数据,整型数据,浮点型数据,excel表中的每一列数据类型都要与你要求的每一列数据里类型匹配。
// 这时就需要我们自己在读取excel表中的数据时,自己去一个一个审查了。审查一般也有两种方式:
// ,表中数据哪一行数据不通过,就过滤掉不通过的数据,通过的数据还按原方式导入,不通过的输出第几行,第几列的错误信息,比如:第二行,第三列,时间格式错误!(可以边判断边导入,一行通过就导入一行)
// ,表中数据只要有一行不通过,整个表中的数据都不能导入,不通过的输出第几行,第几列的错误信息,比如:第二行,第三列,时间格式错误!(先判断后导入,就是先对整个表数据进行匹配,只要都通过了,才能导入) 我在这里做的事第二种方式,至于选哪种方式要根据业务情况的。下面就是如何匹配数据了。
// 比如我要导入的数据有四行,第一行时string,第二行是:int 第三行是:float 第四行是:datatime 格式是(//) 注意:时间格式要尽量定一个统一模式 for (int row = ; row <= rowCount; row++)//在excel表中第一行是标题,所以数据是从第二行开始的。
{
for (int col = ; col <= ColCount; col++)
{
if (col>&&col<)
{
if (worksheet.Cells[row, col].Value.ToString().Length == )//表中数据有可能是空,如果是字符格式就无所谓了,但是如果是整型或者浮点型,那就要判一下,给个默认值0了
{
worksheet.Cells[row, col].Value = ;
}
if (!Regex.IsMatch(worksheet.Cells[row, col].Value.ToString(), @"^[+-]?\d*[.]?\d*$"))//大家知道,整型可以转浮点型,例如:float a 可以 a=1.0 也可以 a=1所以两个一块直接判断了。
{
if (isTrue == false)
{
sb.Append("导入文件失败!" + "\t");
sb.Append(" 有一下错误:" + "\t");
}
sb.Append("第" + row + "行" + col + "列数据类型错误!" + "\t");
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 ==)
{
if (SelectDateTime(worksheet.Cells[row, col].Value.ToString()))//判断时间格式在SelectDatatime方法中处理的,在下面
{
if (isTrue == false)
{
sb.Append("导入文件失败!" + "\t");
sb.Append(" 有一下错误:" + "\t");
}
sb.Append("第" + row + "行" + col + "列时间格式类型错误!" + "\t");
isTrue = true;
}
}
}
sb.Append(Environment.NewLine);//重新起一行
}
if (isTrue == true)
{
return Content(sb.ToString()); //如果isture==true 说明有错误数据就直接返回错误数据,就不再进行导入操作了。
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
下面是,如果所有数据都匹配成功了,那就要执行导入操作了。
for (int row = ; row <= rowCount; row++)
{
string 第一个数据=worksheet.Cells[Row,].Value.ToString(),
int 第二个数据 = int.Parse(worksheet.Cells[Row,].value.ToString()),
int 第三个数据 =float.Parse(worksheet.Cells[Row,].value.ToString()),
string 第四个数据 =worksheet.Cells[Row,].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 > )
{
//如果不一致,取第一个空格前的字符串。
StrTime = strtime.Substring(, 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 = ; i < ; i++)
{
worksheet.Column(i).Width = ;//设置列宽
}
//添加头
worksheet.Cells[, ].Value = "excel表格第一列标题";
worksheet.Cells[, ].Value = "excel表格第二列标题";
worksheet.Cells[, ].Value = "excel表格第三列标题";
worksheet.Cells[, ].Value = "excel表格第四列标题";
if (dtList != null && dtList.Rows.Count > )
{
//添加值
int Count = ;
for (int i = ; i < dtList.Rows.Count; i++)
{
Count++;
DataRow item = dtList.Rows[i];//创建行
worksheet.Cells[Count, ].Value = item[数据库中数据参数名].ToString();
worksheet.Cells[Count, ].Value = item[数据库中数据参数名].ToString();
worksheet.Cells[Count, ].Value = item[数据库中数据参数名].ToString();
worksheet.Cells[Count, ].Value = item[数据库中数据参数名].ToString(); } }
package.Save();//保存
} return File(sFileName, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "导出数据.xlsx");//导出excel表格
}
好了,到这里excel报表的导入导出就介绍完了。希望对一些朋友有些帮助。
.net core excel导入导出的更多相关文章
- .Net Core Excel导入导出神器Npoi.Mapper
前言 我们在日常开发中对Excel的操作可能会比较频繁,好多功能都会涉及到Excel的操作.在.Net Core中大家可能使用Npoi比较多,这款软件功能也十分强大,而且接近原始编程.但是直接使用Np ...
- .Net core NPOI导入导出Excel
最近在想.net core NPOI 导入导出Excel,一开始感觉挺简单的,后来真的遇到很多坑.所以还是写一篇博客让其他人少走一些弯路,也方便忘记了再重温一遍.好了,多的不说,直接开始吧. 在.Ne ...
- Octopus——excel导入导出工具
Octopus Octopus是一个简易的Excel导入导出工具.目前主要就两个功能: 导入:将excel中一行数据转换为指定的java对象,并通过指定的正则表达式检查合法性. 导出:按照给定的xml ...
- java简易excel导入导出工具(封装POI)
Octopus 如何导入excel 如何导出excel github项目地址 Octopus Octopus 是一个简单的java excel导入导出工具. 如何导入excel 下面是一个excel文 ...
- 利用反射实现通用的excel导入导出
如果一个项目中存在多种信息的导入导出,为了简化代码,就需要用反射实现通用的excel导入导出 实例代码如下: 1.创建一个 Book类,并编写set和get方法 package com.bean; p ...
- Excel导入导出的业务进化场景及组件化的设计方案(上)
1:前言 看过我文章的网友们都知道,通常前言都是我用来打酱油扯点闲情的. 自从写了上面一篇文章之后,领导就找我谈话了,怕我有什么想不开. 所以上一篇的(下)篇,目前先不出来了,哪天我异地二次回忆的时候 ...
- 关于Excel导入导出的用例设计
目前,为方便操作,很多系统都会增加批量导入导出的功能.文件导入导出一般格式都是excel.由于用户直接在excel在填写内容,无法控制填写的格 式,加上excel解析比较困难,所以一般涉及到excel ...
- ASP.NET 之 常用类、方法的超级总结,并包含动态的EXCEL导入导出功能,奉上类库源码
实用类:UtilityClass 包含如下方法 判断对象是否为空或NULL,如果是空或NULL返回true,否则返回false 验证手机号是否正确 13,15,18 验证邮箱 验证网址 MD5加密,返 ...
- Excel导入导出帮助类
/// <summary> /// Excel导入导出帮助类 /// 记得引入 NPOI /// 下载地址 http://npoi.codeplex.com/rele ...
随机推荐
- JAVA Random 详解
Java中存在着两种Random函数: 一.java.lang.Math.Random; 调用这个Math.Random()函数能够返回带正号的double值,该值大于等于0.0且小于1.0,即取值范 ...
- IIC协议解析
(1)概述 I2C(Inter-Integrated Circuit BUS) 集成电路总线,该总线由NXP(原PHILIPS)公司设计,多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距 ...
- Golang的标识符命名规则
Golang的标识符命名规则 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.关键字 1>.Go语言有25个关键字 Go语言的25个关键字如下所示: break,defau ...
- 解决Elasticsearch索引只读
今天添加索引时发现kibana添加索引不生效,页面也没有报错,没有创建成功只是一闪而过. 另外发现各项目日志与当前时间差异很大,filebeat一直报错io timeout 具体报错如下: fileb ...
- C++面试常见问题——06数组排序
数组排序 冒泡.最简单的冒泡,没啥好讲的 #include<iostream> using namespace std; void BubbleSort(int a[],int len){ ...
- Ubuntu跨版本安装软件
更新到Ubuntu 19.10之后,源里的Goldendict就会不时的崩溃,让我十分心累.过了这么长时间也一直没有更新,估计在20.04之前是不会更新了.这段时间因为疫情不能出门,正好看看这个问题, ...
- 一、JavaScript之第一个实例,点击按钮修改文本内容
一.代码如下: 二.运行后效果如下 三.点击按钮,"曾经沧海难为水"变成了日期事件了 <!DOCTYPE html> <html> <meta htt ...
- 088-PHP数组运用 - 通过循环函数过滤部分数组
<?php function myfunc(&$arr){ //自定义一个过滤函数 $j=count($arr); for($i=0;$i<$j;$i++){ if($arr[$i ...
- React 学习笔记(1) 基础语法和生命周期
参看:视频地址 简单搭建一个react-cli: 2. React.createElement() 将object转化为 React语法 import React from 'react' impor ...
- window下mysql-proxy简单使用
mysql-proxy是mysql官方提供的mysql中间件服务,上游可接入若干个mysql-client,后端可连接若干个mysql-server.它使用mysql协议,任何使用mysql-clie ...