2017-10-17 29 views
1

Je crée une action de contrôleur MVC dans laquelle les données JSON transmises à la méthode doivent être écrites dans un fichier Excel. À l'heure actuelle, je teste la fonctionnalité en utilisant des données codées en dur à partir d'un tableau de données basé sur l'exemple de this blog post.Comment enregistrer un fichier Excel en C#

Voici le code que j'ai:

[HttpPost] 
     public ActionResult ExportData() 
      { 
       Microsoft.Office.Interop.Excel.Application excel; 
       Microsoft.Office.Interop.Excel.Workbook worKbooK; 
       Microsoft.Office.Interop.Excel.Worksheet worKsheeT; 
       Microsoft.Office.Interop.Excel.Range celLrangE; 

       try 
       { 
        excel = new Microsoft.Office.Interop.Excel.Application(); 
        excel.Visible = false; 
        excel.DisplayAlerts = false; 
        worKbooK = excel.Workbooks.Add(Type.Missing); 


        worKsheeT = (Microsoft.Office.Interop.Excel.Worksheet)worKbooK.ActiveSheet; 
        worKsheeT.Name = "StudentRepoertCard"; 

        worKsheeT.Range[worKsheeT.Cells[1, 1], worKsheeT.Cells[1, 8]].Merge(); 
        worKsheeT.Cells[1, 1] = "Student Report Card"; 
        worKsheeT.Cells.Font.Size = 15; 


        int rowcount = 2; 

        foreach (DataRow datarow in ExportToExcel().Rows) 
        { 
         rowcount += 1; 
         for (int i = 1; i <= ExportToExcel().Columns.Count; i++) 
         { 

          if (rowcount == 3) 
          { 
           worKsheeT.Cells[2, i] = ExportToExcel().Columns[i - 1].ColumnName; 
           worKsheeT.Cells.Font.Color = System.Drawing.Color.Black; 

          } 

          worKsheeT.Cells[rowcount, i] = datarow[i - 1].ToString(); 

          if (rowcount > 3) 
          { 
           if (i == ExportToExcel().Columns.Count) 
           { 
            if (rowcount % 2 == 0) 
            { 
             celLrangE = worKsheeT.Range[worKsheeT.Cells[rowcount, 1], worKsheeT.Cells[rowcount, ExportToExcel().Columns.Count]]; 
            } 

           } 
          } 

         } 

        } 

        celLrangE = worKsheeT.Range[worKsheeT.Cells[1, 1], worKsheeT.Cells[rowcount, ExportToExcel().Columns.Count]]; 
        celLrangE.EntireColumn.AutoFit(); 
        Microsoft.Office.Interop.Excel.Borders border = celLrangE.Borders; 
        border.LineStyle = Microsoft.Office.Interop.Excel.XlLineStyle.xlContinuous; 
        border.Weight = 2d; 

        celLrangE = worKsheeT.Range[worKsheeT.Cells[1, 1], worKsheeT.Cells[2, ExportToExcel().Columns.Count]]; 

        worKbooK.SaveAs("\\root\\test.xlsx"); 
        worKbooK.Close(); 
        excel.Quit(); 

       } 
       catch (Exception ex) 
       { 
        return Json(new { saveSuccess = false }, JsonRequestBehavior.AllowGet); 

       } 
       finally 
       { 
        worKsheeT = null; 
        celLrangE = null; 
        worKbooK = null; 

       } 

       return Json(new { saveSuccess = true }, JsonRequestBehavior.AllowGet); 
      } 
      //private void Form1_Load(object sender, EventArgs e) 
      //{ 
      // dataGridView1.DataSource = ExportToExcel(); 
      //} 
      public System.Data.DataTable ExportToExcel() 
      { 
       System.Data.DataTable table = new System.Data.DataTable(); 
       table.Columns.Add("ID", typeof(int)); 
       table.Columns.Add("Name", typeof(string)); 
       table.Columns.Add("Sex", typeof(string)); 
       table.Columns.Add("Subject1", typeof(int)); 
       table.Columns.Add("Subject2", typeof(int)); 
       table.Columns.Add("Subject3", typeof(int)); 
       table.Columns.Add("Subject4", typeof(int)); 
       table.Columns.Add("Subject5", typeof(int)); 
       table.Columns.Add("Subject6", typeof(int)); 
       table.Rows.Add(1, "Amar", "M", 78, 59, 72, 95, 83, 77); 
       table.Rows.Add(2, "Mohit", "M", 76, 65, 85, 87, 72, 90); 
       table.Rows.Add(3, "Garima", "F", 77, 73, 83, 64, 86, 63); 
       table.Rows.Add(4, "jyoti", "F", 55, 77, 85, 69, 70, 86); 
       table.Rows.Add(5, "Avinash", "M", 87, 73, 69, 75, 67, 81); 
       table.Rows.Add(6, "Devesh", "M", 92, 87, 78, 73, 75, 72); 
       return table; 
      } 

En ce moment, le code fonctionne jusqu'au moment où la sauvegarde se produit. Pour une raison quelconque, l'emplacement du fichier est introuvable. Je supposais que le nom du fichier devait être listé à la fin du chemin après le dossier contenant afin de fournir le nom, mais peut-être ce n'est pas la bonne façon de spécifier le chemin du fichier.

Ce que je dois réellement faire est de permettre à l'utilisateur de choisir l'emplacement du fichier dans l'explorateur de fichiers, fournir un nom, puis enregistrer le fichier. Puisque c'est le cas, le chemin du fichier devrait être fourni dynamiquement. J'ai regardé beaucoup de publications et articles de SO mais je n'ai pas vu un exemple clair de la façon de faire cela.

Comment le code doit-il être modifié pour que l'utilisateur puisse spécifier le nom et le chemin du fichier?

+0

permettent l'utilisateur à choisir l'emplacement pour enregistrer le fichier où? dans un dossier du serveur? Je ne suis pas sûr que je comprenne – derloopkat

+0

@derloopkat sur leur machine locale. Ils doivent essentiellement être en mesure de télécharger le fichier Excel. – loremIpsum1771

+0

Je ne suis pas une personne MVC mais j'ai eu de mauvaises expériences avec Microsoft.Office.Interop.Excel. Assurez-vous que vous n'avez pas de processus EXCEL.exe après l'exécution de votre programme. Si vous êtes intéressé par une meilleure approche pour construire des fichiers Xml, j'utiliserais OpenXml. Ce [link] (https://blogs.msdn.microsoft.com/brian_jones/2010/06/22/writing-large-excel-files-with-the-open-xml-sdk/) section "SAX" est un bon tutoriel. –

Répondre

2

Vous ne pouvez pas choisir d'enregistrer le fichier depuis leur navigateur. Vous devez servir le fichier et le laisser le télécharger et l'enregistrer où il veut.

En outre, le serveur vous voulez une application ASP.NET de production déployé à probablement ne dispose pas d'une copie d'Excel installé (et même si elle Interop est un peu à mon humble avis en désordre) si vous voulez probablement utiliser un OpenXml bibliothèque comme EPPlus à la place.

Cela vous permettra de faire quelque chose comme ceci:

public IActionResult ExportData() 
{ 
    using (var excel = new ExcelPackage()) 
    { 
     var wks = excel.Workbook.Worksheets.Add("StudentReportCard"); 
     wks.Cells[1,1].LoadFromCollection(GetStudentRecords(), PrintHeaders:true); 
     return File(excel.GetAsByteArray(),"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "export.xlsx"); 
    }; 
} 
private static IEnumerable<StudentRecord> GetStudentRecords() 
{ 
    yield return new StudentRecord 
    { 
     Id = 1, 
     Name = "John", 
     Subject = "Maths", 
     Score = 77.9 
    }; 
    yield return new StudentRecord 
    { 
     Id = 2, 
     Name = "Jane", 
     Subject = "Maths", 
     Score = 78.9 
    }; 
    yield return new StudentRecord 
    { 
     Id = 3, 
     Name = "Jo", 
     Subject = "Maths", 
     Score = 99.9 
    }; 
} 

qui envoie un fichier comme celui-ci nommé « export.xlsx » pour l'utilisateur d'enregistrer à partir de leur navigateur:

enter image description here

+0

Est-ce un paquet de nuget, je ne vois que des versions de mise à jour sur github. Si ce n'est plus sur Nuget, y a-t-il une autre bibliothèque qui pourrait faire cela que vous recommanderiez? – loremIpsum1771

+0

oui, c'est un paquet de nuget: https://www.nuget.org/packages/EPPlus/ (ou, un port non officiel si vous utilisez le noyau aspnet: https://www.nuget.org/packages/EPPlus.core /) –

+0

essayez aussi https://www.easyxls.com/net-excel-library –