Ответ 1
К сожалению, невозможно прочитать таблицу из потока с LinqToExcel.
Это потому, что он использует OLEDB для чтения из электронных таблиц и не может читать из потока.
Как я могу прочитать электронную таблицу Excel, которая была только что отправлена на мой сервер? Я искал что-то, но я только нашел, как читать электронную таблицу Excel с пути имени файла, который не является моим случаем.
Мне нужно что-то вроде этого:
public ActionResult Import(HttpPostedFileBase file)
{
var excel = new ExcelQueryFactory(file); //using linq to excel
}
К сожалению, невозможно прочитать таблицу из потока с LinqToExcel.
Это потому, что он использует OLEDB для чтения из электронных таблиц и не может читать из потока.
Я столкнулся с той же проблемой, но я не хотел переключаться на платный сервис, так что это то, что я сделал.
public class DataImportHelper : IDisposable
{
private readonly string _fileName;
private readonly string _tempFilePath;
public DataImportHelper(HttpPostedFileBase file, string tempFilePath)
{
_fileName = file.FileName;
_tempFilePath = Path.Combine(tempFilePath, _fileName);
(new FileInfo(_tempFilePath)).Directory.Create();
file.SaveAs(_tempFilePath);
}
public IQueryable<T> All<T>(string sheetName = "")
{
if (string.IsNullOrEmpty(sheetName))
{
sheetName = (typeof (T)).Name;
}
var excelSheet = new ExcelQueryFactory(_tempFilePath);
return from t in excelSheet.Worksheet<T>(sheetName)
select t;
}
public void Dispose()
{
File.Delete(_tempFilePath);
}
}
Вот тест
[Fact]
public void AcceptsAMemoryStream()
{
MemoryFile file;
using (var f = File.OpenRead("SampleData.xlsx"))
{
file = new MemoryFile(f, "multipart/form-data", "SampleData.xlsx");
using (var importer = new DataImportHelper(file, "Temp/"))
{
var products = importer.All<Product>();
Assert.NotEmpty(products);
}
}
}
Вот MemoryFile.cs. Этот файл используется только для тестирования. Это всего лишь реализация HttpPostedFileBase, поэтому вы можете проверить свои контроллеры и мой маленький помощник. Это было заимствовано из другого поста.
public class MemoryFile : HttpPostedFileBase
{
Stream stream;
string contentType;
string fileName;
public MemoryFile(Stream stream, string contentType, string fileName)
{
this.stream = stream;
this.contentType = contentType;
this.fileName = fileName;
}
public override int ContentLength
{
get { return (int)stream.Length; }
}
public override string ContentType
{
get { return contentType; }
}
public override string FileName
{
get { return fileName; }
}
public override Stream InputStream
{
get { return stream; }
}
public override void SaveAs(string filename)
{
using (var file = File.Open(filename, FileMode.Create))
stream.CopyTo(file);
}
}
Вы можете использовать свойство InputStream
HttpPostedFileBase
, чтобы прочитать таблицу Excel в памяти.
Я использую ClosedXML пакет nuget для чтения содержимого excel из потока, доступного в вашем случае. Он имеет простую перегрузку, которая берет поток, указывающий на поток для файла excel (aka workbook).
импортированные пространства имен в верхней части файла кода:
using ClosedXML.Excel;
Исходный код:
public ActionResult Import(HttpPostedFileBase file)
{
//HttpPostedFileBase directly is of no use so commented your code
//var excel = new ExcelQueryFactory(file); //using linq to excel
var stream = file.InputStream;
if (stream.Length != 0)
{
//handle the stream here
using (XLWorkbook excelWorkbook = new XLWorkbook(stream))
{
var name = excelWorkbook.Worksheet(1).Name;
//do more things whatever you like as you now have a handle to the entire workbook.
var firstRow = excelWorkbook.Worksheet(1).Row(1);
}
}
}
Вам нужны сборки Office Interops. Для справки Объектная модель Excel.