需要能够在ASP.NET中读取使用FileUploadControl上载的Excel文件。该解决方案将托管在服务器上。我不想将Excel文件存储在服务器上。 我想直接将excel内容转换为数据集或数据表并使用。
以下是我已经找到的两种解决方案,但对我不起作用。
LINQTOEXCEL - 当您在本地计算机上有excel文件并且在本地计算机上运行代码时,此方法有效。在我的例子中,用户正在尝试使用服务器上托管的网页从本地计算机上传excel文件。
ExcelDataReader - 我目前正在使用这个,但这是第三方工具。我无法将此转移给我们的客户。此外,如果行/列交叉点携带公式,则该行/列交集的数据不会被读入数据集。
当excel和.NET解决方案都在同一台机器上时,我在google和StackOverflow上找到的大多数建议都有效。但在我的网站上,当解决方案托管在服务器上时,我需要它才能工作,并且用户正在尝试使用本地计算机上的托管网页上载Excel。 如果您有任何其他建议,可以告诉我吗?
答案 0 :(得分:34)
您可以使用HttpPostedFile
的{{3}}属性将文件读入内存。
以下是一个示例,说明如何使用 InputStream
从DataTable
的{{1}}创建IO.Stream
:
HttpPostedFile
这是 VB.NET版本:
protected void UploadButton_Click(Object sender, EventArgs e)
{
if (FileUpload1.HasFile && Path.GetExtension(FileUpload1.FileName) == ".xlsx")
{
using (var excel = new ExcelPackage(FileUpload1.PostedFile.InputStream))
{
var tbl = new DataTable();
var ws = excel.Workbook.Worksheets.First();
var hasHeader = true; // adjust accordingly
// add DataColumns to DataTable
foreach (var firstRowCell in ws.Cells[1, 1, 1, ws.Dimension.End.Column])
tbl.Columns.Add(hasHeader ? firstRowCell.Text
: String.Format("Column {0}", firstRowCell.Start.Column));
// add DataRows to DataTable
int startRow = hasHeader ? 2 : 1;
for (int rowNum = startRow; rowNum <= ws.Dimension.End.Row; rowNum++)
{
var wsRow = ws.Cells[rowNum, 1, rowNum, ws.Dimension.End.Column];
DataRow row = tbl.NewRow();
foreach (var cell in wsRow)
row[cell.Start.Column - 1] = cell.Text;
tbl.Rows.Add(row);
}
var msg = String.Format("DataTable successfully created from excel-file. Colum-count:{0} Row-count:{1}",
tbl.Columns.Count, tbl.Rows.Count);
UploadStatusLabel.Text = msg;
}
}
else
{
UploadStatusLabel.Text = "You did not specify a file to upload.";
}
}
为了完整起见,这是aspx:
Sub UploadButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
If (FileUpload1.HasFile AndAlso IO.Path.GetExtension(FileUpload1.FileName) = ".xlsx") Then
Using excel = New ExcelPackage(FileUpload1.PostedFile.InputStream)
Dim tbl = New DataTable()
Dim ws = excel.Workbook.Worksheets.First()
Dim hasHeader = True ' change it if required '
' create DataColumns '
For Each firstRowCell In ws.Cells(1, 1, 1, ws.Dimension.End.Column)
tbl.Columns.Add(If(hasHeader,
firstRowCell.Text,
String.Format("Column {0}", firstRowCell.Start.Column)))
Next
' add rows to DataTable '
Dim startRow = If(hasHeader, 2, 1)
For rowNum = startRow To ws.Dimension.End.Row
Dim wsRow = ws.Cells(rowNum, 1, rowNum, ws.Dimension.End.Column)
Dim row = tbl.NewRow()
For Each cell In wsRow
row(cell.Start.Column - 1) = cell.Text
Next
tbl.Rows.Add(row)
Next
Dim msg = String.Format("DataTable successfully created from excel-file Colum-count:{0} Row-count:{1}",
tbl.Columns.Count, tbl.Rows.Count)
UploadStatusLabel.Text = msg
End Using
Else
UploadStatusLabel.Text = "You did not specify an excel-file to upload."
End If
End Sub
答案 1 :(得分:2)
//Best Way To read file direct from stream
IExcelDataReader excelReader = null;
//file.InputStream is the file stream stored in memeory by any ways like by upload file control or from database
int excelFlag = 1; //this flag us used for execl file format .xls or .xlsx
if (excelFlag == 1)
{
//1. Reading from a binary Excel file ('97-2003 format; *.xls)
excelReader = ExcelReaderFactory.CreateBinaryReader(file.InputStream);
}
else if(excelFlag == 2)
{
//2. Reading from a OpenXml Excel file (2007 format; *.xlsx)
excelReader = ExcelReaderFactory.CreateOpenXmlReader(file.InputStream);
}
if (excelReader != null)
{
//...
//3. DataSet - The result of each spreadsheet will be created in the result.Tables
ds = excelReader.AsDataSet();
//...
////4. DataSet - Create column names from first row
//excelReader.IsFirstRowAsColumnNames = true;
//DataSet result = excelReader.AsDataSet();
////5. Data Reader methods
//while (excelReader.Read())
//{
// //excelReader.GetInt32(0);
//}
//6. Free resources (IExcelDataReader is IDisposable)
excelReader.Close();
}
答案 2 :(得分:0)
也许你可以看看Koogra这是一个开源的Excel阅读器(只读作者)我想你会从客户端获得一个流。然后你可以做你现在正在做的所有事情从内存流中读取并写入数据库。
我希望这会有所帮助。
答案 3 :(得分:0)
这是使用ClosedXML.Excel在MVC中执行此操作的方法。我知道这个答案为时已晚。我只是想在google搜索问题之后为所有登陆此页面的人提供这个答案。在Visual Studio中,单击工具菜单并展开NuGet包管理器,然后运行包管理器控制台。键入以下命令:
Install-Package ClosedXML
模特:
namespace ExcelUploadFileDemo.Models
{
public class UploadFile
{
[Required]
public HttpPostedFileBase ExcelFile { get; set; }
}
}
控制器:
namespace ExcelUploadFileDemo.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
UploadFile UploadFile = new UploadFile();
return View(UploadFile);
}
[HttpPost]
public ActionResult Index(UploadFile UploadFile)
{
if (ModelState.IsValid)
{
if (UploadFile.ExcelFile.ContentLength > 0)
{
if (UploadFile.ExcelFile.FileName.EndsWith(".xlsx") || UploadFile.ExcelFile.FileName.EndsWith(".xls"))
{
XLWorkbook Workbook;
Try//incase if the file is corrupt
{
Workbook = new XLWorkbook(UploadFile.ExcelFile.InputStream);
}
catch (Exception ex)
{
ModelState.AddModelError(String.Empty, $"Check your file. {ex.Message}");
return View();
}
IXLWorksheet WorkSheet = null;
Try//incase if the sheet you are looking for is not found
{
WorkSheet = Workbook.Worksheet("sheet1");
}
catch
{
ModelState.AddModelError(String.Empty, "sheet1 not found!");
return View();
}
WorkSheet.FirstRow().Delete();//if you want to remove ist row
foreach (var row in WorkSheet.RowsUsed())
{
//do something here
row.Cell(1).Value.ToString();//Get ist cell. 1 represent column number
}
}
else
{
ModelState.AddModelError(String.Empty, "Only .xlsx and .xls files are allowed");
return View();
}
}
else
{
ModelState.AddModelError(String.Empty, "Not a valid file");
return View();
}
}
return View();
}
}
}
此链接有许多示例,显示处理各种excel的不同方法。
https://github.com/ClosedXML/ClosedXML/tree/9ac4d868a313f308b82e94617b9cc2d28baeb1c3/ClosedXML
视图
@model ExcelUploadFileDemo.Models.UploadFile
@{
ViewBag.Title = "Upload Excel File";
}
<h2>Upload an Excel File</h2>
@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-horizontal">
@Html.ValidationSummary("", new { @class = "text-danger" });
<div class="form-group">
@Html.LabelFor(model => model.ExcelFile, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextBoxFor(model => model.ExcelFile, new { type = "file", @class = "form-control" })
@Html.ValidationMessageFor(model => model.ExcelFile, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type = "submit" value="Submit" class="btn btn-default" />
</div>
</div>
</div>
}