如何使用ASP.NET的OleDb類(lèi)庫(kù)操作Excel文件
一、使用背景
Excel表格是一種體現(xiàn)數(shù)據(jù)直觀,又能分析篩選數(shù)據(jù)的強(qiáng)大工具。比如說(shuō)納稅申報(bào)表、財(cái)務(wù)報(bào)表、工資表、成績(jī)排名表、數(shù)據(jù)采集表等等都是Excel,表格形式體現(xiàn)。
特別地,在進(jìn)行數(shù)據(jù)庫(kù)操作中,對(duì)于批量的數(shù)據(jù)的采集,單筆從UI層控件錄入不僅效率低下,而且容易出錯(cuò),Excel表格提供數(shù)據(jù)采集的方式跟高效又便捷。
但是,在代碼的世界中要怎么,通過(guò)非視覺(jué)可視化操作,代碼的形式去驅(qū)動(dòng)excel工作表呢?
我們可以在Oledb數(shù)據(jù)源中找到答案,它提供了一系列接口規(guī)范,可以以Excel表格作為數(shù)據(jù)源操作,進(jìn)行增刪查改。
二、操作流程
1.引用OldDb類(lèi)庫(kù)命名空間,未安裝需要右擊項(xiàng)目-管理Nuget程序包搜索OleDb安裝上。
using System.Data.OleDb;
2.設(shè)置Excel表格模版規(guī)范:命名表頭,按需要采集數(shù)據(jù);

2.后端代碼編寫(xiě):通過(guò).ashx一般處理程序獲取前段提交的Excel文件,建立OleDB數(shù)據(jù)連接。這里以導(dǎo)入商品數(shù)據(jù)為例,進(jìn)行數(shù)據(jù)的預(yù)覽。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
using iTextSharp;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;
using System.Data.OleDb;
namespace MySolution1
{
/// <summary>
/// 建立前端適配的映射類(lèi)
/// </summary>
class ReqParams
{
public string type { get; set; }
public int payload { get; set; }
}
/// <summary>
/// Handler1 的摘要說(shuō)明
/// </summary>
public class Handler1 : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
//創(chuàng)建序列化工具
JavaScriptSerializer serializer = new JavaScriptSerializer();
//獲取前端提交的JSON字符串
string jsonString = context.Request.Form["param"].ToString();
//反序列化映射JSON字符串
ReqParams req = serializer.Deserialize<ReqParams>(jsonString);
//需要返回前端的狀態(tài)
object state = null;
switch (req.type)
{
case "init":
state = new
{
time = DateTime.Now.ToLongTimeString(),
result=req.payload+1,
};
break;
case "uploadFile":
//有文件上傳負(fù)載到Request中,才下一步操作
if (context.Request.Files.Count > 0)
{
HttpPostedFile file = context.Request.Files["file"];
//制定文件保存路徑
string savePath = context.Server.MapPath("~/Content/images/") + file.FileName;
try
{
//保存文件,記錄狀態(tài)信息
file.SaveAs(savePath);
state = new
{
time = DateTime.Now.ToLongTimeString(),
result = "上傳成功",
payload = req.payload + 1,
url = "/Content/images/" + file.FileName,
};
}
catch(Exception e)
{
//保存失敗,拋出錯(cuò)誤信息
state = new
{
time = DateTime.Now.ToLongTimeString(),
result = "上傳失敗!" + e.Message.ToString(),
payload=-1
};
}
}
break;
case "getScorePDF":
state = CreatePDF(context);
break;
case "previewExcelData":
state = PreviewExcelData(context);
break;
}
context.Response.Write(serializer.Serialize(state));
}
object PreviewExcelData(HttpContext context)
{
if(context.Request.Files.Count>0)
{
//獲取客戶(hù)端提交的excel文件
HttpPostedFile excel = context.Request.Files["excel"];
//保存到本地目錄
string path = context.Server.MapPath("~/Content/") + excel.FileName;
excel.SaveAs(path);
//建立excel數(shù)據(jù)源連接
string connectionString = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={path};Extended Properties='Excel 12.0 Xml;HDR=YES;'";
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
try
{
string sql = "select * from [sheet1$]";
//提供容器盛放業(yè)務(wù)數(shù)據(jù)
List<GoodsInfo> list = new List<GoodsInfo>();
conn.Open();
//獲取數(shù)據(jù)讀取器
OleDbDataReader dr = new OleDbCommand(sql, conn).ExecuteReader(System.Data.CommandBehavior.CloseConnection);
//循環(huán)讀取數(shù)據(jù),添加到容器中
while (dr.Read())
{
list.Add(new GoodsInfo()
{
GoodsId=Convert.ToString(dr[0]),
GoodsName = Convert.ToString(dr[1]),
GoodsPrice = Convert.ToDecimal(dr[2]),
GoodsDesc = Convert.ToString(dr[3]),
});
}
return new
{
data=list,
time = DateTime.Now.ToString(),
success = true,
payload = 1,
};
}
finally
{
conn.Close();
}
}
}
else
{
return new
{
errorMsg="未獲取到文件信息!",
time=DateTime.Now.ToString(),
success=false,
payload=-1,
};
}
}
object CreatePDF(HttpContext context)
{
Random ran = new Random(60);
//指定pdf文件目錄
string path = context.Server.MapPath("~/Content/") + "scorePDF.pdf";
//創(chuàng)建pdf文檔、pdf寫(xiě)入器
Document pdf = new Document(PageSize.A4, 10, 10, 40, 30);
PdfWriter writer = PdfWriter.GetInstance(pdf, new FileStream(path, FileMode.Create));
// 指定中文字體(如微軟雅黑)
string fontPath = @"C:\Windows\Fonts\msyh.ttc,0"; // 微軟雅黑
BaseFont baseFont = BaseFont.CreateFont(fontPath,
BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font chineseFont = new Font(baseFont, 8);
try
{
pdf.Open();
//建立表格對(duì)象
PdfPTable table = new PdfPTable(3 + 3 + 3);
//添加表格的單元格數(shù)據(jù)
table.AddCell(new PdfPCell(new Phrase("姓名", chineseFont)));
table.AddCell(new PdfPCell(new Phrase("班級(jí)", chineseFont)));
table.AddCell(new PdfPCell(new Phrase("準(zhǔn)考證", chineseFont)));
table.AddCell(new PdfPCell(new Phrase("語(yǔ)文", chineseFont)));
table.AddCell(new PdfPCell(new Phrase("數(shù)學(xué)", chineseFont)));
table.AddCell(new PdfPCell(new Phrase("英語(yǔ)", chineseFont)));
table.AddCell(new PdfPCell(new Phrase("體育", chineseFont)));
table.AddCell(new PdfPCell(new Phrase("美術(shù)", chineseFont)));
table.AddCell(new PdfPCell(new Phrase("勞動(dòng)", chineseFont)));
//也可以添加表格的行
PdfPRow row = new PdfPRow(new PdfPCell[]
{
new PdfPCell(new Phrase("李明",chineseFont)),
new PdfPCell(new Phrase("一年級(jí)二班",chineseFont)),
new PdfPCell(new Phrase("0500090901",chineseFont)),
new PdfPCell(new Phrase(ran.Next(60,100).ToString(),chineseFont)),
new PdfPCell(new Phrase(ran.Next(60,100).ToString(),chineseFont)),
new PdfPCell(new Phrase(ran.Next(60,100).ToString(),chineseFont)),
new PdfPCell(new Phrase(ran.Next(60,100).ToString(),chineseFont)),
new PdfPCell(new Phrase(ran.Next(60,100).ToString(),chineseFont)),
new PdfPCell(new Phrase(ran.Next(60,100).ToString(),chineseFont)),
});
table.Rows.Add(row);
//把表格放入pdf文檔
pdf.Add(table);
return new
{
time = DateTime.Now.ToLongTimeString(),
result = "操作成功!",
url = "/Content/scorePDF.pdf",
success = true
};
}
catch(Exception e)
{
throw new Exception(e.Message.ToString());
}
finally
{
pdf.Close();
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
[Serializable]
class GoodsInfo
{
public string GoodsId { get; set; }
public string GoodsName { get; set; }
public decimal GoodsPrice { get; set; }
public string GoodsDesc { get; set; }
}
}3.前端代碼編寫(xiě):提供input文件上傳控件獲取Excel文件,依據(jù)接口提交網(wǎng)絡(luò)請(qǐng)求給后端,并依據(jù)讀取結(jié)果渲染數(shù)據(jù)進(jìn)行預(yù)覽。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm3.aspx.cs" Inherits="MySolution1.WebForm3" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>使用ASP.NET讀取Excel表格</title>
<script src="Scripts/jquery-1.10.2.min.js"></script>
</head>
<body>
<div>
<input type="file" id="excel" />
<button onclick="readExcel()">數(shù)據(jù)讀取</button>
</div>
<div >
<table id="data-table" border="1" cellspacing="0" cellpadding="0">
<thead>
<tr>
<td>商品代碼</td>
<td>商品名稱(chēng)</td>
<td>商品價(jià)格</td>
<td>商品備注</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</body>
</html>
<script type="text/javascript">
function readExcel() {
//配置參數(shù)對(duì)接后端
const param = {
"type": "previewExcelData",
"payload":0
}
//獲取負(fù)載的excel文件
const excel = $("#excel")[0].files
const formData=new FormData()
formData.append("param", JSON.stringify(param))
formData.append("excel", excel[0])
//發(fā)送請(qǐng)求到后端
$.ajax({
"url":"/Handler1.ashx",
"type":"post",
"data":formData,
"processData":false,
"contentType":false,
"success":res=>{
const data = JSON.parse(res)
if (data.success) {
alert("讀取成功!")
$("#data-table tbody").html(null)
data.data.map(i=> {
$("#data-table tbody").append("<tr>" + "<td>" + i.GoodsId + "</td>" + "<td>" + i.GoodsName + "</td>" + "<td>" + i.GoodsPrice + "</td>" + "<td>" + i.GoodsDesc + "</td>" + "</tr>")
})
}else{
alert("讀取失敗!"+data.errorMsg)
}
}
})
}
</script>4.編譯運(yùn)行頁(yè)面:上傳Excel文件后,可查看結(jié)果

三、注意事項(xiàng)
1.Excel模版設(shè)置需要和后臺(tái)讀取接口保持一致,例如上述商品管理的Excel導(dǎo)入模版的數(shù)據(jù)和后臺(tái)讀取表格的列是一一對(duì)應(yīng)的;
2.數(shù)據(jù)庫(kù)操作需要進(jìn)行一定的異常處理(例如try-catch-finally),避免讀取數(shù)據(jù)連接未關(guān)閉;
3.確保Excel文件來(lái)源的安全性,數(shù)據(jù)導(dǎo)入模版是事先設(shè)定好、經(jīng)過(guò)視圖加密的,防范宏病毒;
到此這篇關(guān)于如何使用ASP.NET的OleDb類(lèi)庫(kù)操作Excel文件的文章就介紹到這了,更多相關(guān)asp.net oledb類(lèi)庫(kù)操作excel內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ASP.NET Core 數(shù)據(jù)保護(hù)(Data Protection)中篇
這篇文章主要為大家再一次介紹了ASP.NET Core 數(shù)據(jù)保護(hù)(Data Protection),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
ASP.NE網(wǎng)站發(fā)布注意事項(xiàng)簡(jiǎn)析
ASP.NET網(wǎng)站部署到IIS中的關(guān)鍵點(diǎn),本文介紹了一些ASP.NE網(wǎng)站在發(fā)布是需要注意事項(xiàng),需要了解的朋友可以參考下2012-12-12
.NET讀寫(xiě)Excel工具Spire.Xls使用 對(duì)數(shù)據(jù)操作與控制(4)
這篇文章主要為大家詳細(xì)介紹了.NET讀寫(xiě)Excel工具Spire.Xls使用,對(duì)數(shù)據(jù)操作與控制的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
asp.net 用繼承方法實(shí)現(xiàn)頁(yè)面判斷session
在做ASP項(xiàng)目的時(shí)候,判斷用戶(hù)是否登陸常用的方法是在每個(gè)頁(yè)面判斷session是否存在,無(wú)奈用java的時(shí)候過(guò)濾器就用的不熟。。。還是用繼承吧。汗。。。2009-09-09
asp.net編程獲取項(xiàng)目根目錄實(shí)現(xiàn)方法集合
這篇文章主要介紹了asp.net編程獲取項(xiàng)目根目錄實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析總結(jié)了asp.net針對(duì)項(xiàng)目目錄的操作技巧與注意事項(xiàng),需要的朋友可以參考下2015-11-11
ASP.NET 4中的可擴(kuò)展輸出緩存(可以緩存頁(yè)面/控件等)
ASP.NET 1.0引入輸出緩存的概念,這使得開(kāi)發(fā)者可以緩存頁(yè)面、控件、控制器以及HTTP響應(yīng)的輸出到內(nèi)存中,接下來(lái)詳細(xì)介紹,感興趣的朋友可以了解下2013-01-01
.NET?Core使用Redis實(shí)現(xiàn)創(chuàng)建分布式鎖
分布式鎖一般用于確保在分布式系統(tǒng)中,同一時(shí)間只有一個(gè)進(jìn)程可以執(zhí)行某段代碼,本文將通過(guò).NET?Core使用Redis實(shí)現(xiàn)創(chuàng)建分布式鎖,感興趣的可以了解下2025-01-01

