2012-05-10 7 views
7

मैं ओपनएक्सएमएल का उपयोग कर एएसपी.NET वेब सर्वर से एक्सेल फ़ाइल लिखने का प्रयास कर रहा हूं। मेरे पास लगभग 2100 रिकॉर्ड हैं और ऐसा करने के लिए लगभग 20-30 सेकंड लगते हैं। किसी भी तरह से मैं इसे तेजी से कर सकते हैं? डीबी से 2100 पंक्तियों को पुनः प्राप्त करना एक सेकंड का अंश लेता है। निश्चित नहीं है कि स्मृति में उन्हें क्यों जोड़ना अब और अधिक समय लेगा।.NET OpenXML प्रदर्शन समस्या

नोट: ExcelWriter हमारे कस्टम वर्ग http://msdn.microsoft.com/en-us/library/cc861607.aspx

public static MemoryStream CreateThingReport(List<Thing> things, MemoryStream template) 
    { 
     SpreadsheetDocument spreadsheet = SpreadsheetDocument.Open(template, true); 
     WorksheetPart workSheetPart = spreadsheet.WorkbookPart.WorksheetParts.First(); 

     SharedStringTablePart sharedStringPart = spreadsheet.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First(); 

     Cell cell = null; 
     int index = 0; 

     //create cell formatting for header text 
     Alignment wrappedAlignment = new Alignment { WrapText = true }; 
       uint rowOffset = 2; 

    foreach (Thing t in things) 
     { 
      //Received Date 
      cell = ExcelWriter.InsertCellIntoWorksheet("A", rowOffset, workSheetPart); 
      index = ExcelWriter.InsertSharedStringItem(t.CreateDate.ToShortDateString(), sharedStringPart); 
      cell.CellValue = new CellValue(index.ToString()); 
      cell.DataType = new DocumentFormat.OpenXml.EnumValue<CellValues>(CellValues.SharedString); 

      //Car Part Name 
      cell = ExcelWriter.InsertCellIntoWorksheet("B", rowOffset, workSheetPart); 
      index = ExcelWriter.InsertSharedStringItem(t.CarPart.Name, sharedStringPart); 
      cell.CellValue = new CellValue(index.ToString()); 
      cell.DataType = new DocumentFormat.OpenXml.EnumValue<CellValues>(CellValues.SharedString); 

    rowOffset++; 
    } 

workSheetPart.Worksheet.Save(); 

     spreadsheet.WorkbookPart.Workbook.Save(); 
     spreadsheet.Close(); 

     return template; 

उत्तर

7

तो यह MSDN समुदाय डॉक्स में कोई इसी तरह के प्रदर्शन निहितार्थ में भाग की तरह लग रहा है, लेकिन इसके सभी तरीकों के लिए इस लिंक में कोड से सीधे कर रहे हैं। नीचे दिया गया कोड बहुत अक्षम है। किसी ने हैश टेबल का उपयोग करने की सिफारिश की है।

हमारे समाधान के लिए हमने अभी साझा स्ट्रिंग्स को सम्मिलित कर दिया है और डाउनलोड समय में 1:03 सेकंड से 0:03 सेकंड तक चला गया है।

//Old: (1:03) 
      cell = ExcelWriter.InsertCellIntoWorksheet("A", rowOffset, workSheetPart); 
      index = ExcelWriter.InsertSharedStringItem(thing.CreateDate.ToShortDateString(), sharedStringPart); 
      cell.CellValue = new CellValue(index.ToString()); 
      cell.DataType = new DocumentFormat.OpenXml.EnumValue<CellValues>(CellValues.SharedString); 

//New: (0:03) 
      cell = ExcelWriter.InsertCellIntoWorksheet("A", rowOffset, workSheetPart); 
      cell.CellValue = new CellValue(thing.CreateDate.ToShortDateString()); 
       cell.DataType = new DocumentFormat.OpenXml.EnumValue<CellValues>(CellValues.String); 

MSDN डॉक्स

 private static int InsertSharedStringItem(string text, SharedStringTablePart   shareStringPart) 
    { 
// If the part does not contain a SharedStringTable, create one. 
if (shareStringPart.SharedStringTable == null) 
{ 
    shareStringPart.SharedStringTable = new SharedStringTable(); 
} 

int i = 0; 

// Iterate through all the items in the SharedStringTable. If the text already exists, return its index. 
foreach (SharedStringItem item in shareStringPart.SharedStringTable.Elements<SharedStringItem>()) 
{ 
    if (item.InnerText == text) 
    { 
     return i; 
    } 

    i++; 
} 

// The text does not exist in the part. Create the SharedStringItem and return its index. 
shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(text))); 
shareStringPart.SharedStringTable.Save(); 

return i; 
} 
+0

मुझे एक ही समस्या का सामना करना पड़ रहा है ... मुझे 1000+ पंक्तियां लिखने की ज़रूरत है और कुछ मामलों में 10000+ पंक्तियां और यह नरक की तरह धीमी हो रही है ... यहां आपने कहा है कि आप हैश टेबल का उपयोग कर सकते हैं क्या आप एक उदाहरण दे सकते हैं? या यदि किसी अन्य चीज का उपयोग आपने प्रदर्शन को बेहतर बनाने के लिए किया था ... – kunjee

+0

मैं 500K पंक्तियों को देख रहा हूं। क्या आपने इस पोस्ट के बाद से अन्य सुधार किए हैं? मैं स्मृति उपयोग को कम करने के लिए SAX विधि में स्थानांतरित हो गया हूं। और मैं ~ 1.1 सेकंड प्रति 1000 पंक्तियों को देखता हूं। यदि आप इससे अधिक तेज़ी से प्राप्त करते हैं तो कृपया साझा करें। – CaptainBli

2

@kunjee

आप प्रदर्शन अग्रिम सभी आवश्यक वस्तुओं को बनाने इसलिए प्रत्येक पर जाँच नहीं कर रहे हैं कि चाहते हैं (धीमी समाधान, वे बजाय एक हैश तालिका का उपयोग करना चाहिए) इस विधि का आविष्कार यही कारण है कि साझास्ट्रिंगटेबल को भाग के बजाय पैरामीटर के रूप में पास किया गया है।

शब्दकोश तेज़, अनुक्रमित लुकअप के लिए हैं, लूप के लिए बेहतर प्रदर्शन है। हैशटेबल्स की तुलना में थोड़ा तेज है क्योंकि दृढ़ता से टाइप किया गया है इसलिए मुक्केबाजी की आवश्यकता नहीं है। दृढ़ता से टाइप किया जा रहा है वैसे भी एक बड़ा लाभ है।

private static int InsertSharedStringItem(string sharedString, SharedStringTable sharedStringTable, Dictionary<string, int> sharedStrings) 
{ 
    int sharedStringIndex; 

    if (!sharedStrings.TryGetValue(sharedString, out sharedStringIndex)) 
    { 
     // The text does not exist in the part. Create the SharedStringItem now. 
     sharedStringTable.AppendChild(new SharedStringItem(new Text(sharedString))); 

     sharedStringIndex = sharedStrings.Count; 

     sharedStrings.Add(sharedString, sharedStringIndex); 
    } 

    return sharedStringIndex; 
} 
4

@The इंटरनेट

ध्यान दें कि स्ट्रिंग डेटा प्रकार, सूत्र के लिए वास्तव में है पाठ InlineString का उपयोग करना चाहिए के लिए। देखें 17.18.11 ST_CellType (सेल प्रकार):

  • inlineStr (इनलाइन स्ट्रिंग) - सेल एक (इनलाइन) अमीर स्ट्रिंग, अर्थात युक्त, एक नहीं साझा स्ट्रिंग तालिका में। यदि इस सेल प्रकार का उपयोग किया जाता है, तो कक्ष मान सेल (सी तत्व) में v तत्व के बजाय तत्व में है।
  • स्ट्र (स्ट्रिंग) - सेल में एक सूत्र स्ट्रिंग है।
2

बड़ा improment मेरे लिए यह 10 मिनट से 1 मिनट के लिए बदल 500 रिकॉर्ड के लिए पाश

//Save data 
     shareStringPart.SharedStringTable.Save(); 
     worksheetPart.Worksheet.Save(); 

का अधिकाधिक लाभ उठाएं सहेजें() फ़ंक्शन है।

+0

यह ओपनएक्सएमएल के साथ काम करने का एक बहुत ही महत्वपूर्ण हिस्सा है - चूंकि कई उप-वर्गों को एक सहेजने की आवश्यकता होती है, इसलिए हम बाहरी स्कोप के बजाय एकवचन क्रिया विधियों या लूप के अंदर सहेजते हैं जहां बचत अधिक प्रदर्शनकारी होती है। –