2012-12-18 18 views
12

Jak mogę odczytać arkusz kalkulacyjny Excel, który właśnie został wysłany na mój serwer? Szukałem czegoś, ale znalazłem tylko jak odczytać arkusz kalkulacyjny Excela ze ścieżką nazwy pliku, która nie jest moim przypadkiem.Czytanie arkusza kalkulacyjnego Excel w pamięci

muszę coś takiego:

public ActionResult Import(HttpPostedFileBase file) 
{ 
    var excel = new ExcelQueryFactory(file); //using linq to excel 
} 
+1

Możliwy duplikat to pytanie: [Read excel plik ze strumienia] (http: // stackoverflow .pl/questions/560435/read-excel-file-from-a-stream)? –

+0

Musisz wziąć pod uwagę następujące problemy: Co zrobić, jeśli tabela nie znajduje się na pierwszym arkuszu? Co jeśli nie jest w podanym zakresie? Excel ma zdolności OleDb, ale musisz użyć metod takich jak 'GetOleDbSchema()', aby uzyskać zakładki, a następnie znać zakres do zapytania. Jest to możliwe, ale nie jest to tylko 3 linie kodu. –

+0

@DominicZukiewicz To nie jest prawdziwy problem w moim przypadku, ponieważ każdy przesyłany plik będzie miał ten sam schemat. – MuriloKunze

Odpowiedz

13

Niestety nie można odczytać arkusza kalkulacyjnego ze strumienia za pomocą LinqToExcel.

Dzieje się tak, ponieważ używa OLEDB do odczytu z arkusza kalkulacyjnego i nie może odczytać ze strumienia.

19

Wystąpiłem w tym samym numerze, ale nie chciałem przejść na płatną usługę, więc to właśnie zrobiłem.

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); 
    } 

} 

Oto test

[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); 

      } 
     } 
    } 

Oto MemoryFile.cs. Ten plik służy tylko do testowania. Jest to tylko implementacja HttpPostedFileBase, dzięki czemu można przetestować kontrolerów i mojego małego pomocnika. Zostało to pożyczone z innego postu.

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); 
     } 
    } 
+0

Dobrze, zrobiłem coś takiego, aby rozwiązać mój problem. – MuriloKunze

+0

Dzięki Brett Allred, pomogło! – escist

0

Można użyć właściwości InputStream z HttpPostedFileBase do zapoznania się z arkusza kalkulacyjnego Excel w pamięci.

Używam pakietu nuget ClosedXML do odczytywania zawartości programu Excel ze strumienia dostępnego w twoim przypadku. Ma proste przeciążenie, które pobiera strumień wskazujący strumień dla pliku Excela (aka skoroszytu).

importowane nazw w górnej części pliku Kod:

using ClosedXML.Excel; 

Źródło:

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); 
     } 
    } 
} 
Powiązane problemy