- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章C#的Excel导入、导出由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本篇主要介绍c#的excel导入、导出,供大家参考,具体内容如下 。
一. 介绍 1.1 第三方类库:npoi 。
说明:npoi是poi项目的.net 版本,可用于excel、word的读写操作.
优点:不用装office环境.
下载地址:http://npoi.codeplex.com/releases 。
1.2 excel结构介绍 。
工作簿(workbook):每个excel文件可理解为一个工作簿.
工作表(sheet):一个工作簿(workbook)可以包含多个工作表.
行(row):一个工作表(sheet)可以包含多个行.
二. excel导入 2.1 操作流程 。
2.2 npoi操作代码 。
说明:把excel文件转换为list<t> 。
步骤:
①读取excel文件并以此初始化一个工作簿(workbook); 。
②从工作簿上获取一个工作表(sheet);默认为工作薄的第一个工作表; 。
③遍历工作表所有的行(row);默认从第二行开始遍历,第一行(序号0)为单元格头部; 。
④遍历行的每一个单元格(cell),根据一定的规律赋值给对象的属性.
代码:
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
/// <summary>
/// 从excel2003取数据并记录到list集合里
/// </summary>
/// <param name="cellheard">单元头的key和value:{ { "username", "姓名" }, { "age", "年龄" } };</param>
/// <param name="filepath">保存文件绝对路径</param>
/// <param name="errormsg">错误信息</param>
/// <returns>转换好的list对象集合</returns>
private
static
list<t> excel2003toentitylist<t>(dictionary<
string
,
string
> cellheard,
string
filepath,
out
stringbuilder errormsg) where t :
new
()
{
errormsg =
new
stringbuilder();
// 错误信息,excel转换到实体对象时,会有格式的错误信息
list<t> enlist =
new
list<t>();
// 转换后的集合
list<
string
> keys = cellheard.keys.tolist();
// 要赋值的实体对象属性名称
try
{
using
(filestream fs = file.openread(filepath))
{
hssfworkbook workbook =
new
hssfworkbook(fs);
hssfsheet sheet = (hssfsheet)workbook.getsheetat(0);
// 获取此文件第一个sheet页
for
(
int
i = 1; i <= sheet.lastrownum; i++)
// 从1开始,第0行为单元头
{
// 1.判断当前行是否空行,若空行就不在进行读取下一行操作,结束excel读取操作
if
(sheet.getrow(i) ==
null
)
{
break
;
}
t en =
new
t();
string
errstr =
""
;
// 当前行转换时,是否有错误信息,格式为:第1行数据转换异常:xxx列;
for
(
int
j = 0; j < keys.count; j++)
{
// 2.若属性头的名称包含'.',就表示是子类里的属性,那么就要遍历子类,eg:useren.truename
if
(keys[j].indexof(
"."
) >= 0)
{
// 2.1解析子类属性
string
[] properotyarray = keys[j].split(
new
string
[] {
"."
}, stringsplitoptions.removeemptyentries);
string
subclassname = properotyarray[0];
// '.'前面的为子类的名称
string
subclassproperotyname = properotyarray[1];
// '.'后面的为子类的属性名称
system.reflection.propertyinfo subclassinfo = en.gettype().getproperty(subclassname);
// 获取子类的类型
if
(subclassinfo !=
null
)
{
// 2.1.1 获取子类的实例
var subclassen = en.gettype().getproperty(subclassname).getvalue(en,
null
);
// 2.1.2 根据属性名称获取子类里的属性信息
system.reflection.propertyinfo properotyinfo = subclassinfo.propertytype.getproperty(subclassproperotyname);
if
(properotyinfo !=
null
)
{
try
{
// excel单元格的值转换为对象属性的值,若类型不对,记录出错信息
properotyinfo.setvalue(subclassen, getexcelcelltoproperty(properotyinfo.propertytype, sheet.getrow(i).getcell(j)),
null
);
}
catch
(exception e)
{
if
(errstr.length == 0)
{
errstr =
"第"
+ i +
"行数据转换异常:"
;
}
errstr += cellheard[keys[j]] +
"列;"
;
}
}
}
}
else
{
// 3.给指定的属性赋值
system.reflection.propertyinfo properotyinfo = en.gettype().getproperty(keys[j]);
if
(properotyinfo !=
null
)
{
try
{
// excel单元格的值转换为对象属性的值,若类型不对,记录出错信息
properotyinfo.setvalue(en, getexcelcelltoproperty(properotyinfo.propertytype, sheet.getrow(i).getcell(j)),
null
);
}
catch
(exception e)
{
if
(errstr.length == 0)
{
errstr =
"第"
+ i +
"行数据转换异常:"
;
}
errstr += cellheard[keys[j]] +
"列;"
;
}
}
}
}
// 若有错误信息,就添加到错误信息里
if
(errstr.length > 0)
{
errormsg.appendline(errstr);
}
enlist.add(en);
}
}
return
enlist;
}
catch
(exception ex)
{
throw
ex;
}
}
|
2.3 c#逻辑操作代码 。
说明:对excel转换后的list<t>进行后续操作;如:检测有效性、持久化存储等等 。
步骤:
①调用2.2代码,把excel文件转换为list<t>.
②对list<t>进行有效性检测:必填项是否为空、是否有重复记录等等.
③对list<t>进行持久化存储操作。如:存储到数据库.
④返回操作结果.
代码:
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
public
void
importexcel(httpcontext context)
{
stringbuilder errormsg =
new
stringbuilder();
// 错误信息
try
{
#region 1.获取excel文件并转换为一个list集合
// 1.1存放excel文件到本地服务器
httppostedfile filepost = context.request.files[
"filed"
];
// 获取上传的文件
string
filepath = excelhelper.saveexcelfile(filepost);
// 保存文件并获取文件路径
// 单元格抬头
// key:实体对象属性名称,可通过反射获取值
// value:属性对应的中文注解
dictionary<
string
,
string
> cellheader =
new
dictionary<
string
,
string
> {
{
"name"
,
"姓名"
},
{
"age"
,
"年龄"
},
{
"gendername"
,
"性别"
},
{
"transcriptsen.chinesescores"
,
"语文成绩"
},
{
"transcriptsen.mathscores"
,
"数学成绩"
},
};
// 1.2解析文件,存放到一个list集合里
list<userentity> enlist = excelhelper.exceltoentitylist<userentity>(cellheader, filepath,
out
errormsg);
#endregion
#region 2.对list集合进行有效性校验
#region 2.1检测必填项是否必填
for
(
int
i = 0; i < enlist.count; i++)
{
userentity en = enlist[i];
string
errormsgstr =
"第"
+ (i + 1) +
"行数据检测异常:"
;
bool
ishavenoinputvalue =
false
;
// 是否含有未输入项
if
(
string
.isnullorempty(en.name))
{
errormsgstr +=
"姓名列不能为空;"
;
ishavenoinputvalue =
true
;
}
if
(ishavenoinputvalue)
// 若必填项有值未填
{
en.isexcelvaildateok =
false
;
errormsg.appendline(errormsgstr);
}
}
#endregion
#region 2.2检测excel中是否有重复对象
for
(
int
i = 0; i < enlist.count; i++)
{
userentity ena = enlist[i];
if
(ena.isexcelvaildateok ==
false
)
// 上面验证不通过,不进行此步验证
{
continue
;
}
for
(
int
j = i + 1; j < enlist.count; j++)
{
userentity enb = enlist[j];
// 判断必填列是否全部重复
if
(ena.name == enb.name)
{
ena.isexcelvaildateok =
false
;
enb.isexcelvaildateok =
false
;
errormsg.appendline(
"第"
+ (i + 1) +
"行与第"
+ (j + 1) +
"行的必填列重复了"
);
}
}
}
#endregion
// todo:其他检测
#endregion
// 3.todo:对list集合持久化存储操作。如:存储到数据库
// 4.返回操作结果
bool
issuccess =
false
;
if
(errormsg.length == 0)
{
issuccess =
true
;
// 若错误信息成都为空,表示无错误信息
}
var rs =
new
{ success = issuccess, msg = errormsg.tostring(), data = enlist };
system.web.script.serialization.javascriptserializer js =
new
system.web.script.serialization.javascriptserializer();
context.response.contenttype =
"text/plain"
;
context.response.write(js.serialize(rs));
// 返回json格式的内容
}
catch
(exception ex)
{
throw
ex;
}
}
|
3. excel导出 3.1 导出流程 。
3.2 npoi操作代码 。
说明:把list<t>转换为excel 。
步骤:
①创建一个工作簿(workbook); 。
②在工作簿上创建一个工作表(sheet); 。
③在工作表上创建第一行(row),第一行为列头,依次写入cellheard的值(做为列名).
④循环遍历list<t>集合,每循环一遍创建一个行(row),然后根据cellheard的键(属性名称)依次从list<t>中的实体对象取值存放到单元格内.
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
/// <summary>
/// 实体类集合导出到excle2003
/// </summary>
/// <param name="cellheard">单元头的key和value:{ { "username", "姓名" }, { "age", "年龄" } };</param>
/// <param name="enlist">数据源</param>
/// <param name="sheetname">工作表名称</param>
/// <returns>文件的下载地址</returns>
public
static
string
entitylisttoexcel2003(dictionary<
string
,
string
> cellheard, ilist enlist,
string
sheetname)
{
try
{
string
filename = sheetname +
"-"
+ datetime.now.tostring(
"yyyymmddhhmmssfff"
) +
".xls"
;
// 文件名称
string
urlpath =
"upfiles/excelfiles/"
+ filename;
// 文件下载的url地址,供给前台下载
string
filepath = httpcontext.current.server.mappath(
"\"
+ urlpath);
// 文件路径
// 1.检测是否存在文件夹,若不存在就建立个文件夹
string
directoryname = path.getdirectoryname(filepath);
if
(!directory.exists(directoryname))
{
directory.createdirectory(directoryname);
}
// 2.解析单元格头部,设置单元头的中文名称
hssfworkbook workbook =
new
hssfworkbook();
// 工作簿
isheet sheet = workbook.createsheet(sheetname);
// 工作表
irow row = sheet.createrow(0);
list<
string
> keys = cellheard.keys.tolist();
for
(
int
i = 0; i < keys.count; i++)
{
row.createcell(i).setcellvalue(cellheard[keys[i]]);
// 列名为key的值
}
// 3.list对象的值赋值到excel的单元格里
int
rowindex = 1;
// 从第二行开始赋值(第一行已设置为单元头)
foreach
(var en
in
enlist)
{
irow rowtmp = sheet.createrow(rowindex);
for
(
int
i = 0; i < keys.count; i++)
// 根据指定的属性名称,获取对象指定属性的值
{
string
cellvalue =
""
;
// 单元格的值
object
properotyvalue =
null
;
// 属性的值
system.reflection.propertyinfo properotyinfo =
null
;
// 属性的信息
// 3.1 若属性头的名称包含'.',就表示是子类里的属性,那么就要遍历子类,eg:useren.username
if
(keys[i].indexof(
"."
) >= 0)
{
// 3.1.1 解析子类属性(这里只解析1层子类,多层子类未处理)
string
[] properotyarray = keys[i].split(
new
string
[] {
"."
}, stringsplitoptions.removeemptyentries);
string
subclassname = properotyarray[0];
// '.'前面的为子类的名称
string
subclassproperotyname = properotyarray[1];
// '.'后面的为子类的属性名称
system.reflection.propertyinfo subclassinfo = en.gettype().getproperty(subclassname);
// 获取子类的类型
if
(subclassinfo !=
null
)
{
// 3.1.2 获取子类的实例
var subclassen = en.gettype().getproperty(subclassname).getvalue(en,
null
);
// 3.1.3 根据属性名称获取子类里的属性类型
properotyinfo = subclassinfo.propertytype.getproperty(subclassproperotyname);
if
(properotyinfo !=
null
)
{
properotyvalue = properotyinfo.getvalue(subclassen,
null
);
// 获取子类属性的值
}
}
}
else
{
// 3.2 若不是子类的属性,直接根据属性名称获取对象对应的属性
properotyinfo = en.gettype().getproperty(keys[i]);
if
(properotyinfo !=
null
)
{
properotyvalue = properotyinfo.getvalue(en,
null
);
}
}
// 3.3 属性值经过转换赋值给单元格值
if
(properotyvalue !=
null
)
{
cellvalue = properotyvalue.tostring();
// 3.3.1 对时间初始值赋值为空
if
(cellvalue.trim() ==
"0001/1/1 0:00:00"
|| cellvalue.trim() ==
"0001/1/1 23:59:59"
)
{
cellvalue =
""
;
}
}
// 3.4 填充到excel的单元格里
rowtmp.createcell(i).setcellvalue(cellvalue);
}
rowindex++;
}
// 4.生成文件
filestream file =
new
filestream(filepath, filemode.create);
workbook.write(file);
file.close();
// 5.返回下载路径
return
urlpath;
}
catch
(exception ex)
{
throw
ex;
}
}
|
3.3 c#逻辑操作代码 。
说明:对excel转换后的list<t>进行后续操作;如:检测有效性、持久化存储等等 。
步骤:
①获取list<t>集合.
②调用3.2,将list<t>转换为excel文件.
③服务器存储excel文件并返回下载链接.
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
public
void
exportexcel(httpcontext context)
{
try
{
// 1.获取数据集合
list<userentity> enlist =
new
list<userentity>() {
new
userentity{name=
"刘一"
,age=22,gender=
"male"
,transcriptsen=
new
transcriptsentity{chinesescores=80,mathscores=90}},
new
userentity{name=
"陈二"
,age=23,gender=
"male"
,transcriptsen=
new
transcriptsentity{chinesescores=81,mathscores=91} },
new
userentity{name=
"张三"
,age=24,gender=
"male"
,transcriptsen=
new
transcriptsentity{chinesescores=82,mathscores=92} },
new
userentity{name=
"李四"
,age=25,gender=
"male"
,transcriptsen=
new
transcriptsentity{chinesescores=83,mathscores=93} },
new
userentity{name=
"王五"
,age=26,gender=
"male"
,transcriptsen=
new
transcriptsentity{chinesescores=84,mathscores=94} },
};
// 2.设置单元格抬头
// key:实体对象属性名称,可通过反射获取值
// value:excel列的名称
dictionary<
string
,
string
> cellheader =
new
dictionary<
string
,
string
> {
{
"name"
,
"姓名"
},
{
"age"
,
"年龄"
},
{
"gendername"
,
"性别"
},
{
"transcriptsen.chinesescores"
,
"语文成绩"
},
{
"transcriptsen.mathscores"
,
"数学成绩"
},
};
// 3.进行excel转换操作,并返回转换的文件下载链接
string
urlpath = excelhelper.entitylisttoexcel2003(cellheader, enlist,
"学生成绩"
);
system.web.script.serialization.javascriptserializer js =
new
system.web.script.serialization.javascriptserializer();
context.response.contenttype =
"text/plain"
;
context.response.write(js.serialize(urlpath));
// 返回json格式的内容
}
catch
(exception ex)
{
throw
ex;
}
}
|
3.4 代码分析 。
核心代码主要是cellheader与list<t>之间的映射关系:
四. 源码下载 4.1 运行图 。
源码下载:c-excel.rar 。
以上就是本文的全部内容,希望能够对大家的学习有所帮助.
最后此篇关于C#的Excel导入、导出的文章就讲到这里了,如果你想了解更多关于C#的Excel导入、导出的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我想制作一个引用另一个 excel 文件中的单元格的公式。我已经弄清楚了,如下所示: ='C:\Users\17\Desktop\[JAN-11 2011.xlsx]1'!$H$44 但由于此工作表中
有谁知道是否可以在 Excel 中生成缺少地址门牌号的报告? 例如,我们在 Apple St (no.5, 9, 11) 有三个地址记录,是否可以生成一个报告: 列出工作簿中每条街道的所有记录街道编号
这个问题已经有答案了: VBA auto hide ribbon in Excel 2013 (7 个回答) 已关闭 4 年前。 我试图在打开工作文件时隐藏我的丝带。 我已点击以下链接,但不断收到运行
我编写了一个 VBA 程序来删除元音。我无法从 excel 调用该函数。我收到 #NAME 错误。下面的代码 Function REMOVEVOWELS(Txt) As String 'Removes
嗨,我正在尝试在 MS excel 中应用一个函数(正确函数) 但是当我编写这个函数并使用填充句柄将其复制到其他单元格时,我在所有复制的单元格中得到相同的输出。 但是当我点击单元格时,引用是好的。但结
假设我有一个格式如下的电子表格: Sheet 1 | Sheet 2 name email | name e
我正在尝试简化财务报告中的数据输入,因此我尝试使用 Excel Visual Basic 制作表格。 到目前为止我做了2个用户表单,以后我会做5个。我做了用户表单,以便数据输入运算符(operator
我需要对单元格公式而不是单元格内容执行 Mid 或 Find。 如果我的单元格公式是: =[功能](Arg1, Arg2, Arg3) 我需要能够将 Arg2 提取到另一个单元格。 如果不使用 VBA
我想用 VBA 管理嵌入在另一个 Excel 文件中的 Excel 文件。我可以使用 .docx 文档找到很多结果,但我坚持使用 .xlsx 文档。 我最后一次尝试是使用 OLE 对象,但停留在“Sa
我最近一直在尝试使用 perl 和一些模块来读取 Excel 文件,尤其是单元格的格式。 例如,我写了一段使用 ParseExcel 模块读取单元格背景颜色的 perl 代码。然而,在测试时我注意到对
我目前正在使用 Maatwebsite 的 Excel 包,并且能够很好地生成一个包含我想要的列和值的表格,但我希望能够生成表格,其他表格位于单个 Excel 工作表的下方。可能吗? 上面附上的屏幕截
我需要以下方面的指导。我有一个包含 150000 条记录的文件 (excel)。收到另一个包含 5000-6000 条记录的 excel 文件,需要根据第二个文件中信息的某些条件删除该行。 我使用字典
我有我认为的标准公式,根据我使用的 Excel 版本、Excel 365 或 Excel 2019 的不同,它的行为会有所不同 =IF(F5=$M$1;IFERROR(IF(AND(IFERROR(F
信息: 我有一个名为 Demo.xlsm 的 Excel 文件 此文件包含一个名为 UserForm1 的用户表单,该用户表单会在打开文件时自动加载。 打开文件时,名为 Demo.xlsm 的工作簿也
我在A Excel工作表中有一个列,其值是1 1 1 2 2 2 3 3 3 4 4 4....,在B Excel工作表中有另一列,其值1 2 4 ....,什么我想要的是从 B 读取值并查看它们是否
所以,我有这个问题,我想通过使用 OR 函数检查调整列的条件来找到列的平均值,我尝试将 OR 放入 AverageIf 函数,失败,还尝试了“Average(IF( OR("再次不是正确的返回。认为这
假设我想要这种类型的formula = SUM(startcell:endcell)的答案,但是startcell和endcell组件发生了变化。 因此,我希望能够使用 和 中的任何值,而不是直接在公
我正在寻找一个简单的 Excel 宏,它可以根据单元格中的特定数字/值将行从一张工作表复制到 Excel 中的另一张工作表。我有两张纸。一个称为“master”,另一个表称为“top10”。 这是数据
我正在尝试调用另一个工作簿中的 Excel 宏。它是一个特定于工作表的宏,但 Microsoft 文档和网上研究给出的语法仅提供了一种仅通过工作簿访问宏的方法。该语法是: Application.Ru
我检查了很多不同的帖子,但似乎找不到我正在寻找的确切代码。另外,我以前从未使用过 VBA,因此我尝试从其他帖子中获取代码并输入我的信息以使其正常工作。还没有运气。在工作中,我们有一个 Excel 薪资
我是一名优秀的程序员,十分优秀!