PHPExcel में यूनिवर्सल सेल रीडिंग

हेलो, हेब्र!
काम पर, मुझे अक्सर PHP का उपयोग करके एक्सेल दस्तावेजों को आयात करना पड़ता है।
इसके लिए, मैं PHPExcel लाइब्रेरी का उपयोग करता हूं , जो आज बहुत सुविधाजनक उपकरण है।
लेकिन कोशिकाओं से डेटा पढ़ने के साथ जुड़े कुछ "फिसलन" क्षण हैं, जो मैं हैब्रेटाटेटेली को बताना चाहता हूं, साथ ही एक फ़ंक्शन को पार्स करना चाहता हूं जो इन समस्याओं को हल करता है।

1. सेल एड्रेसिंग


एक्सेल के साथ काम करने पर कोशिकाओं को संबोधित करने के कई तरीके हैं:

पहली विधि स्थिर कोशिकाओं के लिए अधिक सुविधाजनक है, और दूसरी और तीसरी छोरों के लिए।

लेकिन PHPExcel में इनमें से किसी भी तरीके से सेल प्राप्त करने के लिए कोई सार्वभौमिक कार्य नहीं है, केवल अलग-अलग फ़ंक्शन हैं। खैर, इस चूक को सुधारें:
public function getCellValue($cellOrCol, $row = null) { //column set by index if(is_numeric($cellOrCol)) { $cell = $this->activeSheet->getCellByColumnAndRow($cellOrCol, $row); } else { $lastChar = substr($cellOrCol, -1, 1); if(!is_numeric($lastChar)) { //column contains only letter, eg "A" $cellOrCol .= $row; } $cell = $this->activeSheet->getCell($cellOrCol); } $val = $cell->getValue(); return $val; } 

मैं तुरंत एक आरक्षण कर दूंगा कि जो कोड उदाहरण मैं उद्धृत करता हूं, उसके लिंक $ हैं , क्योंकि ये PHPExcel के ऊपर मेरे आवरण वर्ग की विधियाँ हैं। इस टुकड़े में, सेल ऑब्जेक्ट प्राप्त करने के सभी तीन तरीकों को लागू किया जाता है।

2. कोशिकाओं का विलय


मर्ज किए गए कक्षों को पढ़ते समय, PHPExcel सभी लेकिन पहले के लिए एक खाली मान लौटाता है।
यानी नीचे की छवि के लिए, B3 और C3 के मान खाली रेखाएँ होंगे:



मैं इस व्यवहार से हमेशा असहज रहा हूं।
यह किसी भी मर्ज किए गए सेल के लिए बहुत अधिक सुविधाजनक (और अधिक तार्किक!) है उनके लिए सामान्य मूल्य "मर्जवेल्यू" वापस करने के लिए।
ऐसा करने के लिए, जब एक मूल्य का अनुरोध किया जाता है, तो आपको शीट के सभी संयुक्त रेंज से गुजरना पड़ता है, और यदि निर्दिष्ट सेल सीमा में आती है, तो पहले वापस लौटें:
 $this->mergedCellsRange = $this->activeSheet->getMergeCells(); foreach($this->mergedCellsRange as $currMergedRange) { if($cell->isInRange($currMergedRange)) { $currMergedCellsArray = PHPExcel_Cell::splitRange($currMergedRange); $cell = $this->activeSheet->getCell($currMergedCellsArray[0][0]); break; } } 


3. तारीखें


जैसा कि आप जानते हैं, एक्सेल 1 जनवरी 1900 से दिनों की संख्या के रूप में है। इसलिए, जब ऊपर स्क्रीनशॉट में सेल बी 2 को पढ़ा जाता है, तो हमें एक बेकार 41044 मिलता है। लेकिन अच्छी खबर यह भी है - PHPExcel का एक सुविधाजनक कार्य PHPExcel_Sared_Date :: ExcelToPHP () है , जो php प्रारूप की तारीख को बदल देता है।
यह केवल सही समय पर इस फ़ंक्शन को लागू करने के लिए बनी हुई है:
 $val = $cell->getValue(); if(PHPExcel_Shared_Date::isDateTime($cell)) { $val = date($format, PHPExcel_Shared_Date::ExcelToPHP($val)); } 


4. सूत्र


ज्यादातर मामलों में, मानक फ़ंक्शन $ सेल-> getValue () सूत्रों को सही ढंग से संसाधित करता है और गणना किए गए मान को लौटाता है। लेकिन ऐसी परिस्थितियाँ होती हैं जब कोई सूत्र एक गैर-संकलित पत्रक या अन्य फ़ाइल को संदर्भित करता है जो स्थानीय रूप से उस व्यक्ति द्वारा संग्रहीत किया जाता है जिसने आपको एक्सेल दस्तावेज़ भेजा था। फिर getValue () एक त्रुटि लौटाएगा, हालांकि एक्सेल में नेत्रहीन आप सही मान देख सकते हैं अगर कोई शीट रिकॉउट नहीं था। तथ्य यह है कि एक्सेल पुरानेकैल्यूएटेडवैल्यू को बचाता है, जिसका उपयोग यदि आप शीट को नहीं करते हैं। ऊपर दिए गए आंकड़े में, मैंने इसे सेल बी 4 में दिखाया था - यह पुराने मूल्य को प्रदर्शित करता है, हालांकि इसमें लिंक टूटा हुआ है।
PHPExcel, सौभाग्य से, यह भी जानता है कि पुराने फॉर्मूला मान को कैसे संग्रहीत किया जाए। यह तब उपयोग करने के लिए सुविधाजनक है जब getValue () वर्कआउट नहीं कर सका और मूल्य वापस नहीं किया, लेकिन सूत्र स्वयं (पहला वर्ण "="):

 $val = $cell->getValue(); if((substr($val,0,1) === '=' ) && (strlen($val) > 1)){ $val = $cell->getOldCalculatedValue(); } 


परिणाम


नतीजतन, हमें एक फ़ंक्शन मिला जो आपको सेल वैल्यू को सार्वभौमिक रूप से पढ़ने की अनुमति देता है:
  public function getCellValue($cellOrCol, $row = null, $format = 'dmY') { //column set by index if(is_numeric($cellOrCol)) { $cell = $this->activeSheet->getCellByColumnAndRow($cellOrCol, $row); } else { $lastChar = substr($cellOrCol, -1, 1); if(!is_numeric($lastChar)) { //column contains only letter, eg "A" $cellOrCol .= $row; } $cell = $this->activeSheet->getCell($cellOrCol); } //try to find current coordinate in all merged cells ranges //if find -> get value from head cell foreach($this->mergedCellsRange as $currMergedRange){ if($cell->isInRange($currMergedRange)) { $currMergedCellsArray = PHPExcel_Cell::splitRange($currMergedRange); $cell = $this->activeSheet->getCell($currMergedCellsArray[0][0]); break; } } //simple value $val = $cell->getValue(); //date if(PHPExcel_Shared_Date::isDateTime($cell)) { $val = date($format, PHPExcel_Shared_Date::ExcelToPHP($val)); } //for incorrect formulas take old value if((substr($val,0,1) === '=' ) && (strlen($val) > 1)){ $val = $cell->getOldCalculatedValue(); } return $val; } 


कसौटी


जांचने के लिए, हम स्क्रीनशॉट से एक्सेल को दो तरीकों से पढ़ेंगे: मानक getValue ( # 1 ) और उपरोक्त फ़ंक्शन ( # 2 ) का उपयोग करना:



टेस्ट # 1:

टेस्ट # 2:

जैसा कि आप देख सकते हैं, दूसरे मामले में सब कुछ सही माना गया था।

मरहम में उड़ना


यह ध्यान रखना महत्वपूर्ण है कि आइटम 2, 3, और 4 का उपयोग करना केवल ReadDataOnly = false मोड में काम करता है। यह डिफ़ॉल्ट PHPExcel मोड है जब यह पुस्तक के बारे में सभी मेटा जानकारी को पढ़ता है। मानक छोटे दस्तावेजों जैसे चालान, चालान आदि के लिए उपयुक्त है।
ReadDataOnly = true का समावेश भारी फ़ाइलों के लिए आवश्यक हो सकता है जब केवल सेल मानों की आवश्यकता होती है। मेरे अभ्यास में, ऐसी फ़ाइलों में स्वरूपित टेबल होते हैं और ऐसी कार्यक्षमता की आवश्यकता नहीं होती है।

PHPExcel में रीडिंग मोड सेट करना इस तरह से किया जाता है:
 $objReader = PHPExcel_IOFactory::createReaderForFile($filename); $objReader->setReadDataOnly(false); $this->PHPExcel = $objReader->load($filename); 

आपका ध्यान के लिए धन्यवाद!

Source: https://habr.com/ru/post/In136540/


All Articles