मैं एक्सेल कोशिकाओं में स्ट्रिंग (संख्या नहीं) के रूप में संख्यात्मक तार कैसे पढ़ सकता हूं?


146
  1. मेरे पास ऐसी सामग्री के साथ एक्सेल फाइल है:

    • A1: SomeString

    • A2: 2

    सभी फ़ील्ड स्ट्रिंग प्रारूप पर सेट हैं।

  2. जब मैंने POI का उपयोग करके जावा में फ़ाइल पढ़ी, तो यह बताता है कि A2 संख्यात्मक सेल प्रारूप में है।

  3. समस्या यह है कि A2 में मान 2 या 2.0 हो सकता है (और मैं उन्हें अलग करने में सक्षम होना चाहता हूं) इसलिए मैं अभी उपयोग नहीं कर सकता हूं .toString()

मूल्य को स्ट्रिंग के रूप में पढ़ने के लिए मैं क्या कर सकता हूं?

जवाबों:


319

मुझे भी यही समस्या थी। मैंने cell.setCellType(Cell.CELL_TYPE_STRING);स्ट्रिंग मान को पढ़ने से पहले किया था , जिसने इस समस्या को हल किया था कि उपयोगकर्ता ने सेल को कैसे स्वरूपित किया।


मैं पोई-3.8-बीटा 4 का उपयोग करता हूं, और इसकी उम्मीद के अनुसार काम कर रहा हूं! टीएस इसे उत्तर के रूप में क्यों स्वीकार नहीं करते हैं?
स्वदेव

ज्ञात हो कि स्ट्रिंग रूपांतरण के लिए POI न्यूमेरिक सिस्टम लोकेल को ध्यान में नहीं रखता है, यह हमेशा दशमलव विभाजक के रूप में डॉट का उपयोग करता है। उदाहरण के लिए, यदि आपका सिस्टम "," का उपयोग करता है, और Excel संख्याओं में "1,9" जैसा दिखता है, तो POI बदले में "1.9" लौटाएगा।
एलेक्सी बेरेकिन

53
ध्यान दें कि Apache POI javadocs स्पष्ट रूप से ऐसा नहीं करने के लिए कहती है! जैसा कि वे समझाते हैं, आपको इसके बजाय
डेटाफ़ॉर्मर का

6
ऐसा करने के खिलाफ गाग्राव्र की चेतावनी सही है! डॉक्स से: "यदि आप जो करना चाहते हैं, वह आपके संख्यात्मक सेल के लिए एक स्ट्रिंग मूल्य प्राप्त करना है, तो रोकें --- यह ऐसा करने का तरीका नहीं है। इसके बजाय, एक संख्यात्मक या बूलियन या दिनांक सेल के स्ट्रिंग मान प्राप्त करने के लिए, का उपयोग करें इसके बजाय डेटाफ़ॉर्मर। " poi.apache.org/apidocs/org/apache/poi/ss/usermodel/… जब तक मैं गलती से बदल रहे डेटा को बदलने का इरादा नहीं करता, तब तक मैं खुद इस तकनीक का इस्तेमाल कर रहा था। (स्ट्रिंग का प्रकार सेट करें, मूल्य पढ़ें, संख्यात्मक प्रकार पर वापस सेट करें, फिर से पढ़ें और एक अलग संख्यात्मक मान प्राप्त करें!)
क्रिस फिनाले

6
DataFormatter का उपयोग करें। Javadoc हमें उपरोक्त विधि का उपयोग करने से चेतावनी देता है।
बालू SKT

96

मुझे नहीं लगता कि जब आप सवाल पूछते हैं तो हमारे पास यह वर्ग होता है, लेकिन आज एक आसान जवाब है।

आप क्या करना चाहते हैं डेटाफ़ॉर्मर वर्ग का उपयोग करें । आप इसे एक सेल पास करते हैं, और यह आपको एक स्ट्रिंग वापस करने की पूरी कोशिश करता है जिसमें एक्सेल आपको उस सेल के लिए दिखाएगा। यदि आप इसे एक स्ट्रिंग सेल पास करते हैं, तो आपको स्ट्रिंग वापस मिल जाएगी। यदि आप इसे लागू किए गए प्रारूपण नियमों के साथ एक संख्यात्मक सेल पास करते हैं, तो यह उनके आधार पर संख्या को प्रारूपित करेगा और आपको स्ट्रिंग वापस देगा।

आपके मामले के लिए, मुझे लगता है कि संख्यात्मक कोशिकाओं का पूर्णांक स्वरूपण नियम उन पर लागू होता है। यदि आप DataFormatter को उन कोशिकाओं को प्रारूपित करने के लिए कहते हैं, तो यह आपको पूर्णांक स्ट्रिंग के साथ एक स्ट्रिंग वापस देगा।

यह भी ध्यान दें कि बहुत से लोग ऐसा करने का सुझाव देते हैं cell.setCellType(Cell.CELL_TYPE_STRING), लेकिन Apache POI JavaDocs में स्पष्ट रूप से कहा गया है कि आपको ऐसा नहीं करना चाहिए ! कर setCellTypeकॉल स्वरूपण खो देंगे, के रूप में javadocs समझाने शेष स्वरूपण के साथ एक स्ट्रिंग में कनवर्ट करने के लिए एक ही रास्ता उपयोग करने के लिए है DataFormatter वर्ग


धन्यवाद @Gagravarr केवल मेरे लिए आपके जवाब का काम, <code> cell.setCellType (Cell.CELL_TYPE_STRING); <code> 2.2 मान को 2.2000000000000002 में रूपांतरित करें, लेकिन मुझे 2.2 चाहिए। यह स्ट्रिंग प्रारूप में कुछ भी लौटाता है धन्यवाद
akush yadav

डेटाफ़ॉर्मर फॉर्मूला कोशिकाओं के लिए काम नहीं करता है, यह मान के बजाय सूत्र का एक स्ट्रिंग प्रतिनिधित्व लौटाता है
gaurav5430

1
बस एक मामूली नोट: कृपया ऐसे उत्तरों के लिए संक्षिप्त कोड स्निपेट प्रदान करें,
भले

@ gaurav5430 हाँ, यह सूत्र के साथ अच्छी तरह से नहीं चलता है ... डॉक्टर के अनुसार,When passed a null or blank cell, this method will return an empty String (""). Formulas in formula type cells will not be evaluated.
शरतभवन

53

किसी भी प्रकार के सेल के लिए नीचे दिए गए कोड ने मेरे लिए काम किया।

InputStream inp =getClass().getResourceAsStream("filename.xls"));
Workbook wb = WorkbookFactory.create(inp);
DataFormatter objDefaultFormat = new DataFormatter();
FormulaEvaluator objFormulaEvaluator = new HSSFFormulaEvaluator((HSSFWorkbook) wb);

Sheet sheet= wb.getSheetAt(0);
Iterator<Row> objIterator = sheet.rowIterator();

while(objIterator.hasNext()){

    Row row = objIterator.next();
    Cell cellValue = row.getCell(0);
    objFormulaEvaluator.evaluate(cellValue); // This will evaluate the cell, And any type of cell will return string value
    String cellValueStr = objDefaultFormat.formatCellValue(cellValue,objFormulaEvaluator);

}

4
ठीक काम किया! मेरा सुझाव यह होगा कि फॉर्म्युलावेलेटर को पुनः प्राप्त करने के तरीके को बदल दिया जाए। कार्यपुस्तिका वर्ग getCreationHelper().createFormulaEvaluator()विधि का एक सूत्र मूल्यांकनकर्ता प्रदान करता है । इस तरह आपका कोड HSSFFormulaEvaluator वर्ग के साथ युग्मित नहीं होगा।
विटोर सैंटोस

यह स्वीकृत उत्तर होना चाहिए। धन्यवाद @ विनायक
चरण १२

क्या FormulaEvaluatorबस इस समाधान से हटाया जा सकता है? क्या यह एक उद्देश्य पूरा करता है?
पी। ब्रायन। मैके

1
objFormulaEvaluator.ev मूल्यांकन के लिए कॉल आवश्यक नहीं है। उस का रिटर्न वैल्यू यहां उपयोग नहीं किया जा रहा है।
रादु सिमियोनेस्कु

32

मैं निम्नलिखित दृष्टिकोण की सिफारिश करूंगा जब सेल के प्रकार को संशोधित करना अवांछनीय है:

if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
    String str = NumberToTextConverter.toText(cell.getNumericCellValue())
}

NumberToTextConverter सटीक नुकसान के बिना एक्सेल के नियमों का उपयोग करके एक पाठ में दोहरे मान को सही ढंग से बदल सकता है।


वास्तव में रोमांचक सलाह! धन्यवाद! यह स्ट्रिंग के लिए सेल टाइप को सेट करने के विपरीत अनकवर्ड वैल्यू प्राप्त करने की अनुमति देता है।
ग्लीब इगुनोव

मुझे 25/06/2020 के सेल मूल्य के लिए उत्पादन के रूप में 44007 मिल रहा है। मैं क्या गलत कर रहा हूं?
विनय


10

हां, यह पूरी तरह से काम करता है

की सिफारिश की:

        DataFormatter dataFormatter = new DataFormatter();
        String value = dataFormatter.formatCellValue(cell);

पुराना:

cell.setCellType(Cell.CELL_TYPE_STRING);

यहां तक ​​कि अगर आपको cellफॉर्मूला होने से मूल्य प्राप्त करने में कोई समस्या है, तब भी यह काम करता है।


5
लेकिन आपको दोहरे मूल्यों के लिए इसका उपयोग करने से सावधान रहना होगा। मेरे लिए यह मूल्य 7.999999956589965 में बदल गया ...
क्रिस

2
Apache POI javadocs बहुत स्पष्ट है कि आप इसे इस तरह नहीं करना चाहिए रहे हैं : क्या आप क्या करना चाहते अपने सांख्यिक सेल के लिए एक स्ट्रिंग मान मिलता है, तो रोक !. यह ऐसा करने का तरीका नहीं है। इसके बजाय, किसी संख्यात्मक या बूलियन या दिनांक सेल के स्ट्रिंग मान लाने के लिए, इसके बजाय DataFormatter का उपयोग करें।
गाग्रवेर

4

प्रयत्न:

new java.text.DecimalFormat("0").format( cell.getNumericCellValue() )

संख्या को सही ढंग से प्रारूपित करना चाहिए।


जैसा कि मैं समझता हूं, पूछने वाला 2और के बीच अंतर करने में सक्षम होना चाहता है 2.0। आपका समाधान ऐसा नहीं करेगा। (लेकिन फिर भी, स्टैक ओवरफ्लो में आपका स्वागत है!)
पाओलो एबरमन

1

जब तक सेल नंबर में उपयोगकर्ता प्रकारों से पहले पाठ प्रारूप में है, तब तक पीओआई आपको एक स्ट्रिंग के रूप में मूल्य प्राप्त करने की अनुमति देगा। एक कुंजी यह है कि यदि पाठ के रूप में स्वरूपित सेल के ऊपरी बाएं कोने में एक छोटा हरा त्रिभुज है, तो आप इसके मान को एक स्ट्रिंग के रूप में प्राप्त करने में सक्षम होंगे (हरे रंग का त्रिभुज तब प्रकट होता है जब कोई चीज़ जो एक संख्या प्रतीत होती है एक पाठ प्रारूप में coerced है)। यदि आपके पास पाठ स्वरूपित कक्ष हैं जिनमें संख्याएँ हैं, लेकिन POI आपको उन मानों को स्ट्रिंग्स के रूप में लाने नहीं देगा, तो कुछ चीजें हैं जो आप अनुमति देने के लिए स्प्रेडशीट डेटा पर कर सकते हैं:

  • सेल पर डबल क्लिक करें ताकि सेल के अंदर एडिटिंग कर्सर मौजूद हो, फिर एंटर पर क्लिक करें (जो कि एक बार में केवल एक सेल किया जा सकता है)।
  • Excel 2007 पाठ रूपांतरण फ़ंक्शन (जो एक ही बार में कई कक्षों पर किया जा सकता है) का उपयोग करें।
  • एक और स्थान के लिए अपमानजनक मूल्यों को काटें, स्प्रेडशीट कोशिकाओं को पाठ के रूप में पुन: स्वरूपित करें, फिर पहले कटे हुए मानों को बिना किसी उचित मान के वापस उचित क्षेत्र में वापस कर दें।

एक अंतिम बात जो आप कर सकते हैं, वह यह है कि यदि आप Excel 2007 स्प्रेडशीट से डेटा प्राप्त करने के लिए POI का उपयोग कर रहे हैं, तो आप सेल क्लास 'getRawValue ()' विधि कर सकते हैं। यह परवाह नहीं करता है कि प्रारूप क्या है। यह केवल कच्चे डेटा के साथ एक स्ट्रिंग लौटाएगा।


0

जब हम Apache POI लाइब्रेरी का उपयोग करके MS Excel के न्यूमेरिक सेल वैल्यू को पढ़ते हैं, तो वह इसे न्यूमेरिक के रूप में पढ़ता है। लेकिन कुछ समय बाद हम इसे स्ट्रिंग (जैसे फोन नंबर, आदि) के रूप में पढ़ना चाहते हैं। मैंने इस तरह से इसे किया:

  1. पहले सेल = CONCATENATE ("!, D2) के साथ एक नया कॉलम डालें। मुझे लगता है कि डी 2 आपके फोन-नंबर कॉलम की सेल आईडी है। नई सेल को अंत तक खींचें।

  2. अब यदि आप POI का उपयोग करके सेल पढ़ते हैं, तो यह परिकलित मान के बजाय सूत्र को पढ़ेगा। अब निम्नलिखित करें:

  3. एक और कॉलम जोड़ें

  4. चरण 1 में बनाए गए पूर्ण कॉलम का चयन करें और Edit-> COPY चुनें

  5. चरण 3 में बनाए गए स्तंभ के शीर्ष कक्ष पर जाएं और संपादित करें का चयन करें-> विशेष पेस्ट करें

  6. खुली हुई खिड़की में, "मान" रेडियो बटन का चयन करें

  7. "ओके" चुनें

  8. अब POI API का उपयोग करके पढ़ें ... जावा में पढ़ने के बाद ... बस पहले वर्ण को हटा दें ""!


यदि आपका एक्सेल फाइल अपने आप नहीं बनता है तो क्या यह समाधान उपयोगी नहीं लगता है? (इसके अलावा, आप एक उद्धरण अपने जवाब में डाल सकता है यह लंबे समय से है कि नहीं है?।)
पाउलो Ebermann

हां, इसका उपयोग तब नहीं किया जा सकता है जब कोई एक्सेल फाइल को नहीं बना रहा हो।
आसिफ शहजाद

0

मुझे हजारों की संख्या में डेटा सेट पर एक समान मुद्दा मिला है और मुझे लगता है कि मुझे हल करने का एक सरल तरीका मिल गया है। मुझे एक संख्या से पहले एपोस्ट्रोफ सम्मिलित करने की आवश्यकता थी ताकि एक अलग डीबी आयात हमेशा संख्याओं को पाठ के रूप में देखता हो। इससे पहले 8 नंबर 8.0 के रूप में आयात किया जाएगा।

उपाय:

  • सभी स्वरूपण को सामान्य रखें।
  • यहां मैं मान रहा हूं कि संख्या पंक्ति 1 में शुरू होने वाले कॉलम A में संग्रहीत हैं।
  • कॉलम बी में 'डालें और आवश्यकतानुसार कई पंक्तियों को कॉपी करें। वर्कशीट में कुछ भी नहीं दिखाई देता है, लेकिन सेल पर क्लिक करके आप फॉर्मूला बार में एपोस्टोफ देख सकते हैं।
  • कॉलम C: = B1 और A1 में।
  • कॉलम C में सभी सेल का चयन करें और वैल्यू विकल्प का उपयोग करके कॉलम D में पेस्ट स्पेशल करें।

हे सभी नंबरों को प्रेस्टो करें लेकिन टेक्स्ट के रूप में संग्रहीत।


0

getStringCellValue सेल प्रकार संख्यात्मक है, तो NumberFormatException देता है। यदि आप सेल प्रकार को स्ट्रिंग में बदलना नहीं चाहते हैं, तो आप ऐसा कर सकते हैं।

String rsdata = "";
try {
    rsdata = cell.getStringValue();
} catch (NumberFormatException ex) {
    rsdata = cell.getNumericValue() + "";
}

0

इनमें से कई उत्तर पुराने POI प्रलेखन और कक्षाओं को संदर्भित करते हैं। नवीनतम POI 3.16 में, इंट प्रकार के साथ सेल को हटा दिया गया है

Cell.CELL_TYPE_STRING

यहाँ छवि विवरण दर्ज करें

इसके बजाय सेल टाइप एनम का उपयोग किया जा सकता है।

CellType.STRING 

बस अपने पोम को पोइ डिपेंडेंसी के साथ-साथ पोइ-ओक्सिलम डिपेंडेंसी पर नए 3.16 वर्जन पर अपडेट करना सुनिश्चित करें अन्यथा आपको अपवाद मिलते रहेंगे। इस संस्करण के साथ एक फायदा यह है कि आप उस सेल प्रकार को निर्दिष्ट कर सकते हैं जिस समय सेल पिछले उत्तरों में वर्णित सभी अतिरिक्त चरणों को समाप्त करता है:

titleRowCell = currentReportRow.createCell(currentReportColumnIndex, CellType.STRING);

0

मैं बहुत कुछ नहीं करूंगा, लेकिन मुझे लगता है कि उन्होंने मेरे प्रदर्शन को बहुत दूर तक प्रभावित किया। मैं एक के लिए चला गया Hacky अंतर्निहित कास्टिंग के समाधान:

for (Row row : sheet){
String strValue = (row.getCell(numericColumn)+""); // hack
...

मेरा सुझाव है कि आप ऐसा न करें, मेरी स्थिति के कारण यह काम करता है कि सिस्टम कैसे काम करता है और मेरे पास एक विश्वसनीय फ़ाइल स्रोत है।

Footnote: numColumn एक ऐसा उदाहरण है जो संसाधित फ़ाइल के शीर्षलेख को पढ़ने से उत्पन्न होता है।


0
public class Excellib {
public String getExceldata(String sheetname,int rownum,int cellnum, boolean isString) {
    String retVal=null;
    try {
        FileInputStream fis=new FileInputStream("E:\\Sample-Automation-Workspace\\SampleTestDataDriven\\Registration.xlsx");
        Workbook wb=WorkbookFactory.create(fis);
        Sheet s=wb.getSheet(sheetname);
        Row r=s.getRow(rownum);
        Cell c=r.getCell(cellnum);
        if(c.getCellType() == Cell.CELL_TYPE_STRING)
        retVal=c.getStringCellValue();
        else {
            retVal = String.valueOf(c.getNumericCellValue());
        }

मैंने कोशिश की और यह मेरे लिए काम किया


-1

क्या आप वैसे भी एक्सेल वर्कशीट पर नियंत्रण रखते हैं? क्या कोई टेम्प्लेट है जो उपयोगकर्ताओं को आपको इनपुट देने के लिए है? यदि हां, तो आपके पास इनपुट कोशिकाओं के लिए कोड प्रारूप हो सकता है।




-1

इसने मेरे लिए एकदम सही काम किया।

Double legacyRow = row.getCell(col).getNumericCellValue();
String legacyRowStr = legacyRow.toString();
if(legacyRowStr.contains(".0")){
    legacyRowStr = legacyRowStr.substring(0, legacyRowStr.length()-2);
}

-2

हमारे पास एक ही समस्या थी और हमारे उपयोगकर्ताओं को मूल्य दर्ज करने से पहले कोशिकाओं को 'पाठ' के रूप में प्रारूपित करने के लिए मजबूर किया गया था । इस तरह एक्सेल सही ढंग से संख्याओं को पाठ के रूप में संग्रहीत करता है। यदि स्वरूप को बाद में बदल दिया जाता है, तो Excel केवल उस तरीके को बदलता है, जिसमें मूल्य प्रदर्शित होता है, लेकिन जब तक मान को फिर से दर्ज नहीं किया जाता है, तब तक मूल्य को संग्रहीत करने के तरीके को नहीं बदलता है (उदाहरण के लिए सेल में रिटर्न दबाकर)।

चाहे एक्सेल सही ढंग से मूल्य को संग्रहीत करता है या नहीं, पाठ को हरे रंग के त्रिभुज द्वारा इंगित किया जाता है जो कि सेल के बाएं ऊपरी कोने में एक्सेल प्रदर्शित करता है अगर यह सोचता है कि सेल में एक नंबर है लेकिन पाठ के रूप में तैयार किया गया है।


-3

एक int के लिए डाली तो एक करो .toString()। यह बदसूरत है लेकिन यह काम करता है।


समस्या यह है कि अगर ए 2 में 2.0 है तो मुझे स्ट्रिंग "2.0" प्राप्त करने की आवश्यकता है, और यदि 2 तो स्ट्रिंग "2"।
joycollector
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.