2012-12-18 18 views
12

Come posso leggere un foglio di lavoro Excel appena pubblicato sul mio server? Ho cercato qualcosa ma ho trovato solo come leggere un foglio di calcolo Excel con il percorso del nome del file che non è il mio caso.Leggere un foglio di calcolo Excel nella memoria

ho bisogno di qualcosa di simile:

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

Possibile duplicato di questa domanda: [Leggi file da un flusso excel] (http: // StackOverflow .com/domande/560435/lettura-excel-file-da-un-stream)? –

+0

Dovrai prendere in considerazione problemi come: Cosa succede se il tavolo non è sul primo foglio? Cosa succede se non è nell'intervallo specificato? Excel ha le abilità OleDb, ma devi usare metodi come 'GetOleDbSchema()' per ottenere le schede, quindi conoscere l'intervallo da interrogare. È possibile, ma non sono solo 3 righe di codice. –

+0

@DominicZukiewicz Questo non è un problema reale nel mio caso perché ogni file di caricamento avrà lo stesso schema. – MuriloKunze

risposta

13

Sfortunatamente non è possibile leggere un foglio di calcolo da uno streaming con LinqToExcel.

Ecco perché utilizza OLEDB per leggere dai fogli di calcolo e non può leggere da un flusso.

-1

È necessario assemblee Ufficio Interops. Controllare lo Excel Object Model come riferimento.

+0

Questo in realtà non risponde alla domanda – jAC

19

Stavo correndo il tuo stesso problema ma non volevo passare a un servizio a pagamento quindi questo è quello che ho fatto.

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

} 

Ecco un 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); 

      } 
     } 
    } 

Ecco MemoryFile.cs. Questo file è usato solo per i test. È solo un'implementazione di HttpPostedFileBase in modo da poter testare i controller e il mio piccolo aiuto. Questo è stato preso in prestito da un altro post.

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

Bello, ho fatto qualcosa del genere per risolvere il mio problema. – MuriloKunze

+0

Grazie a Brett Allred, questo ha aiutato! – escist

0

È possibile utilizzare la proprietà di InputStreamHttpPostedFileBase a leggere il foglio di calcolo di Excel in memoria.

Uso il pacchetto ClosedXML nuget per leggere il contenuto di Excel dal flusso disponibile nel vostro caso. Ha un sovraccarico semplice che richiede flusso che punta allo streaming per il file excel (alias la cartella di lavoro).

spazi dei nomi importati nella parte superiore del file di codice: il codice

using ClosedXML.Excel; 

Fonte:

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