2012-08-04 2 views
35

में ओपन एक्सएमएल एसडीके के साथ एक्सेल में डेटाटेबल निर्यात करें कृपया मेरी अंग्रेजी के लिए खेद है। मैं खुले एक्सएमएल एसडीके में नया हूं। मेरे प्रोग्राम में एक्सेल फ़ाइल (टेम्पलेट) पर कुछ डेटा और डेटाटेबल निर्यात करने की क्षमता है टेम्पलेट में मैं कुछ प्लेसहोल्डर को डेटा डालता हूं। यह काम करता है बहुत अच्छा है, लेकिन मैं भी ... मेरे नमूना कोड एक DataTable डालने की आवश्यकता:सी #

using (Stream OutStream = new MemoryStream()) 
{ 
    // read teamplate 
    using (var fileStream = File.OpenRead(templatePath)) 
     fileStream.CopyTo(OutStream); 

    // exporting 
    Exporting(OutStream); 

    // to start 
    OutStream.Seek(0L, SeekOrigin.Begin); 

    // out 
    using (var resultFile = File.Create(resultPath)) 
     OutStream.CopyTo(resultFile); 

अगला विधि

private void Exporting(Stream template) 
{ 
    using (var workbook = SpreadsheetDocument.Open(template, true, new OpenSettings       { AutoSave = true })) 
    { 
     // Replace shared strings 
     SharedStringTablePart sharedStringsPart = workbook.WorkbookPart.SharedStringTablePart; 
     IEnumerable<Text> sharedStringTextElements = sharedStringsPart.SharedStringTable.Descendants<Text>(); 

     DoReplace(sharedStringTextElements); 
     // Replace inline strings 
     IEnumerable<WorksheetPart> worksheetParts = workbook.GetPartsOfType<WorksheetPart>(); 

     foreach (var worksheet in worksheetParts) 
     { 
      DoReplace(worksheet.Worksheet.Descendants<Text>()); 
     } 

     int z = 40; 
     foreach (System.Data.DataRow row in ExcelWorkXLSX.ToOut.Rows) 
     { 
      for (int i = 0; i < row.ItemArray.Count(); i++) 
      { 
       ExcelWorkXLSX.InsertText(workbook, row.ItemArray.ElementAt(i).ToString(), getColumnName(i), Convert.ToUInt32(z)); } 
       z++; 
      } 
     } 

    } 
} 

निर्यात करने के लिए लेकिन उत्पादन DataTable slooooooooooooooooooooooowwwwwww को यह टुकड़ा ...

मैं Excel को डेटाटेबल को तेज़ी से और वास्तव में कैसे निर्यात कर सकता हूं?

+0

आप खुले एक्सएमएल एसडीके का उपयोग करने की आवश्यकता है? – KLIM8D

+0

हम्म ... नहीं, लेकिन खुले एक्सएमएल एसडीके तेजी से पढ़/लिखने एक्सेल फाइलें। मेरे प्रोग्राम में मैं xlsx फ़ाइलों को पढ़ रहा हूं, डाटाग्रिडव्यू (डेटाटेबल का उपयोग करके) डेटा को हथियाने, डेटा को दोबारा जांचें। सबसे पहले मैंने इंटरऑप का इस्तेमाल किया, लेकिन इसे एक्सेल और बहुत धीमी गति की आवश्यकता है। मेरी समस्या केवल निर्यात है। लेकिन, मैं इस पल में बहुत सारे कोड को फिर से लिखना नहीं चाहता :) – user1576474

उत्तर

73

मैं इस त्वरित उदाहरण लिखा था। इससे मेरा काम बनता है। मैंने केवल एक टेबल के साथ एक डेटासेट के साथ इसका परीक्षण किया, लेकिन मुझे लगता है कि यह आपके लिए पर्याप्त हो सकता है।

इस बात पर विचार करें कि मैंने सभी कोशिकाओं को स्ट्रिंग के रूप में माना है (यहां तक ​​कि साझाकरण भी नहीं)। यदि आप SharedStrings का उपयोग करना चाहते हैं तो आपको मेरे नमूना को थोड़ा सा ट्विक करने की आवश्यकता हो सकती है।

संपादित करें: इस काम को करने के लिए WindowsBase और DocumentFormat.OpenXml संदर्भ परियोजना के लिए आवश्यक है।

का आनंद लें,

private void ExportDataSet(DataSet ds, string destination) 
     { 
      using (var workbook = SpreadsheetDocument.Create(destination, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook)) 
      { 
       var workbookPart = workbook.AddWorkbookPart(); 

       workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook(); 

       workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets(); 

       foreach (System.Data.DataTable table in ds.Tables) { 

        var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>(); 
        var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData(); 
        sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData); 

        DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>(); 
        string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart); 

        uint sheetId = 1; 
        if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0) 
        { 
         sheetId = 
          sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1; 
        } 

        DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = table.TableName }; 
        sheets.Append(sheet); 

        DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); 

        List<String> columns = new List<string>(); 
        foreach (System.Data.DataColumn column in table.Columns) { 
         columns.Add(column.ColumnName); 

         DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell(); 
         cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; 
         cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName); 
         headerRow.AppendChild(cell); 
        } 


        sheetData.AppendChild(headerRow); 

        foreach (System.Data.DataRow dsrow in table.Rows) 
        { 
         DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); 
         foreach (String col in columns) 
         { 
          DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell(); 
          cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; 
          cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); // 
          newRow.AppendChild(cell); 
         } 

         sheetData.AppendChild(newRow); 
        } 

       } 
      } 
     } 
+4

मुझे लगता है कि 'वर्कबुक .orkbookPart.Workbook = new ...' और 'workbook.WorkbookPart.Workbook.Sheets = new' foreach loop के बाहर ले जाया जाना चाहिए। अन्यथा, लूप का प्रत्येक पुनरावृत्ति वर्कशीट को प्रतिस्थापित करता है, जिससे एक्सेल फ़ाइल में केवल अंतिम 'डेटाटेबल' होता है। – Brian

+0

@ ब्रायन, इसे इंगित करने के लिए धन्यवाद। यह मूल रूप से काम करता था क्योंकि मैंने केवल एक टेबल के साथ परीक्षण किया था। मैंने बस इसे ठीक किया, क्या यह ठीक दिखता है? – eburgos

+2

हाँ, यह ठीक दिखता है। एक तरफ के रूप में, इससे कोई फर्क नहीं पड़ता, 'मैक्स (एस => एस। शीटआईडी.वैल्यू)' कॉल करने से क्लीनर है। चयन करें (एस => एस। शीटआईडी.वैल्यू) .मैक्स() '। इसी तरह, आपको 'DataRow' में 'डेटाकॉलम' इंडेक्सर होने के बाद 'सूची कॉलम' की आवश्यकता नहीं है; दूसरा 'foreach' 'तालिका' कॉलम 'पर भी पुनरावृत्त कर सकता है। – Brian

0

आप इस libary को देखने का प्रयास कर सकते हैं। मैंने इसे अपनी परियोजनाओं में से एक के लिए उपयोग किया है और इसे विश्वसनीय और तेज़ (मैं केवल डेटा निर्यात करने के लिए उपयोग किया जाता है) के साथ काम करना बहुत आसान पाया है।

http://epplus.codeplex.com/

+0

धन्यवाद! यह एक विचार है! मैं केवल निर्यात के लिए कोशिश करूंगा। – user1576474

11

eburgos, मैं अपने कोड को संशोधित किया गया है थोड़ा क्योंकि आप यह सिर्फ स्प्रेडशीट में उन्हें अधिलेखित किया गया था अपने डेटासेट में कई datatables है जब ताकि आप केवल में एक पत्रक साथ छोड़ दिया गया कार्यपुस्तिका। मैं मूल रूप से उस भाग को स्थानांतरित कर देता हूं जहां लूप से कार्यपुस्तिका बनाई गई है। यहां अद्यतन कोड है।

private void ExportDSToExcel(DataSet ds, string destination) 
{ 
    using (var workbook = SpreadsheetDocument.Create(destination, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook)) 
    { 
     var workbookPart = workbook.AddWorkbookPart(); 
     workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook(); 
     workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets(); 

     uint sheetId = 1; 

     foreach (DataTable table in ds.Tables) 
     { 
      var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>(); 
      var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData(); 
      sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);     

      DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>(); 
      string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart); 

      if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0) 
      { 
       sheetId = 
        sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1; 
      } 

      DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = table.TableName }; 
      sheets.Append(sheet); 

      DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); 

      List<String> columns = new List<string>(); 
      foreach (DataColumn column in table.Columns) 
      { 
       columns.Add(column.ColumnName); 

       DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell(); 
       cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; 
       cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName); 
       headerRow.AppendChild(cell); 
      } 

      sheetData.AppendChild(headerRow); 

      foreach (DataRow dsrow in table.Rows) 
      { 
       DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); 
       foreach (String col in columns) 
       { 
        DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell(); 
        cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; 
        cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); // 
        newRow.AppendChild(cell); 
       } 

       sheetData.AppendChild(newRow); 
      } 
     } 
    } 
} 
+0

धन्यवाद, बस ब्रायन की टिप्पणी देखी और मैंने भी वही किया। – eburgos

0

आप मेरी लाइब्रेरी here पर एक नज़र डाल सकते हैं। प्रलेखन अनुभाग के तहत, आपको डेटा तालिका आयात करने का तरीका मिलेगा।

तुम सिर्फ लिखने के लिए

using (var doc = new SpreadsheetDocument(@"C:\OpenXmlPackaging.xlsx")) { 
    Worksheet sheet1 = doc.Worksheets.Add("My Sheet"); 
    sheet1.ImportDataTable(ds.Tables[0], "A1", true); 
} 

आशा है कि यह मदद करता है!

1

मैंने एक्सेल लेखक को अपना खुद का निर्यात लिखा क्योंकि कुछ भी मेरी आवश्यकताओं को पूरा नहीं करता है। यह तेज़ है और कोशिकाओं के पर्याप्त स्वरूपण की अनुमति देता है। आप इसे

https://openxmlexporttoexcel.codeplex.com/

पर समीक्षा कर सकते हैं मुझे आशा है कि यह मदद करता है।

7

मैंने एक सी #/वीबी.Net "एक्सेल में निर्यात" लाइब्रेरी भी लिखी, जो ओपनएक्सएमएल का उपयोग करता है और (अधिक महत्वपूर्ण रूप से) OpenXmlWriter का भी उपयोग करता है, इसलिए बड़ी फ़ाइलों को लिखते समय आप स्मृति से बाहर नहीं होंगे।

पूर्ण स्रोत कोड, और एक डेमो, यहाँ डाउनलोड किया जा सकता है:

Export to Excel

यह उपयोग करने के लिए मृत आसान है। बस उस फ़ाइल नाम को पास करें जिसे आप लिखना चाहते हैं, और DataTable, DataSet या List<>

CreateExcelFile.CreateExcelDocument(myDataSet, "MyFilename.xlsx"); 

और यदि आप इसे एक ASP.Net आवेदन से कॉल कर रहे हैं, यह HttpResponse पारित करने के लिए बाहर फ़ाइल लिखने के लिए।

CreateExcelFile.CreateExcelDocument(myDataSet, "MyFilename.xlsx", Response); 
+0

लिंक अब मृत है ... – Arwin

+1

क्षमा करें ...! यह जिंदा है और अब फिर लात मार रहा है। –

+0

@ माइकग्लिडहिल किसी भी कामकाज को असीमित तरीके से कर रहा है? एक बड़ी फ़ाइल में लिखने की कोशिश करते समय मुझे स्मृति अपवाद से बाहर निकलता है, मैंने सभी संबंधित पोस्ट पढ़ी हैं, ऐसा लगता है कि यह उपलब्ध स्मृति तक ही सीमित है? – afr0

0

मैं स्वीकार किए जाते हैं जवाब की कोशिश की और संदेश कह मिल गया उत्पन्न उत्कृष्टता फ़ाइल दूषित है जब खोलने की कोशिश कर। मैं कोड के नीचे पंक्ति अंत जोड़ने जैसे कुछ संशोधन करके इसे ठीक करने में सक्षम था।

workbookPart.Workbook.Save();

मैं पोस्ट किया है पूरा कोड @Export DataTable to Excel with Open XML in c#