كيف يمكنني قراءة السلاسل الرقمية في Excel الخلايا سلسلة (الأعداد)?

StackOverflow https://stackoverflow.com/questions/1072561

  •  21-08-2019
  •  | 
  •  

سؤال

  1. لدي ملف اكسل مع هذه المحتويات:

    • A1:SomeString

    • A2:2

    جميع الحقول يتم تعيين شكل سلسلة.

  2. عندما قرأت الملف في جافا باستخدام POI ، يقول أنه A2 في الرقمية تنسيق الخلية.

  3. المشكلة هي أن قيمة A2 يمكن أن يكون 2 أو 2.0 (وأنا تريد أن تكون قادرة على التمييز بينها) بحيث لا أستطيع استخدام .toString().

ماذا يمكنني أن أفعل قراءة قيمة السلسلة ؟

هل كانت مفيدة؟

المحلول

كان لي نفس المشكلة.فعلتُ cell.setCellType(Cell.CELL_TYPE_STRING); قبل قراءة قيمة السلسلة، مما أدى إلى حل المشكلة بغض النظر عن كيفية تنسيق المستخدم للخلية.

نصائح أخرى

لا أعتقد أن هذا الفصل قد استعادنا عندما طرحت السؤال، ولكن اليوم هناك إجابة سهلة.

ما تريد القيام به هو استخدام فئة DataFormatter.تقوم بتمرير هذه الخلية، وتبذل قصارى جهدها لإرجاع سلسلة تحتوي على ما سيظهره لك برنامج Excel لتلك الخلية.إذا مررت لها خلية سلسلة، فسوف تستعيد السلسلة.إذا قمت بتمريرها إلى خلية رقمية مع تطبيق قواعد التنسيق، فسوف تقوم بتنسيق الرقم بناءً عليها وتعيد لك السلسلة.

بالنسبة لحالتك، أفترض أن الخلايا الرقمية لديها قاعدة تنسيق عدد صحيح مطبقة عليها.إذا طلبت من DataFormatter تنسيق تلك الخلايا، فسوف يعطيك سلسلة تحتوي على سلسلة عدد صحيح فيها.

لاحظ أيضًا أن الكثير من الأشخاص يقترحون القيام بذلك cell.setCellType(Cell.CELL_TYPE_STRING), ، لكن ال تشير JavaDocs في Apache POI بوضوح تام إلى أنه لا ينبغي عليك القيام بذلك!القيام ب setCellType ستفقد المكالمة التنسيق، حيث أن ملف شرح جافادوكس الطريقة الوحيدة للتحويل إلى سلسلة مع بقاء التنسيق هي استخدام فئة DataFormatter.

الكود أدناه كان مناسبًا لي لأي نوع من الخلايا.

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);

}

أوصي بالنهج التالي عندما يكون تعديل نوع الخلية غير مرغوب فيه:

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

يمكن لـ NumberToTextConverter تحويل القيمة المزدوجة بشكل صحيح إلى نص باستخدام قواعد Excel دون فقدان الدقة.

كما ذكرنا سابقًا في JavaDocs الخاص بـ Poi (https://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/Cell.html#setCellType%28int%29) لا تستخدم:

cell.setCellType(Cell.CELL_TYPE_STRING);

لكن استخدم:

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

المزيد من الأمثلة على http://massapi.com/class/da/DataFormatter.html

نعم، هذا يعمل على أكمل وجه

مُستَحسَن:

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

قديم:

cell.setCellType(Cell.CELL_TYPE_STRING);

حتى لو كان لديك مشكلة في استرداد قيمة من cell وجود صيغة، لا يزال هذا يعمل.

يحاول:

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

ينبغي تنسيق الرقم بشكل صحيح.

طالما أن الخلية بتنسيق نصي قبل أن يكتب المستخدم الرقم، فستسمح لك النقاط المهمة بالحصول على القيمة كسلسلة.أحد المفاتيح هو أنه إذا كان هناك مثلث أخضر صغير في الزاوية العلوية اليسرى من الخلية التي تم تنسيقها كنص، فستتمكن من استرداد قيمته كسلسلة (يظهر المثلث الأخضر عندما يظهر شيء ما كرقم يتم إجباره على تنسيق النص).إذا كانت لديك خلايا منسقة نصية تحتوي على أرقام، ولكن النقاط المهمة لن تسمح لك بجلب هذه القيم كسلاسل، فهناك بعض الأشياء التي يمكنك القيام بها مع بيانات جدول البيانات للسماح بذلك:

  • انقر نقرًا مزدوجًا على الخلية بحيث يكون مؤشر التحرير موجودًا داخل الخلية، ثم انقر فوق "إدخال" (والذي يمكن القيام به في خلية واحدة فقط في كل مرة).
  • استخدم وظيفة تحويل النص في Excel 2007 (والتي يمكن إجراؤها على خلايا متعددة في وقت واحد).
  • قم بقص القيم المخالفة إلى موقع آخر، وأعد تنسيق خلايا جدول البيانات كنص، ثم أعد لصق القيم التي تم قطعها مسبقًا كـ القيم غير المنسقة العودة إلى المنطقة المناسبة.

شيء أخير يمكنك القيام به هو أنه إذا كنت تستخدم POI للحصول على البيانات من جدول بيانات Excel 2007، فيمكنك استخدام طريقة فئة الخلية "getRawValue()".هذا لا يهم ما هو التنسيق.سيُرجع ببساطة سلسلة تحتوي على البيانات الأولية.

عندما نقرأ قيمة الخلية الرقمية لبرنامج MS Excel باستخدام مكتبة Apache POI، فإنها تقرأها كقيمة رقمية.ولكن في وقت ما نريد أن نقرأها كسلسلة (على سبيل المثال.أرقام الهواتف وغيرها).هذه هي الطريقة التي فعلت ذلك:

  1. قم بإدراج عمود جديد بالخلية الأولى =CONCATENATE("!",D2).أفترض أن D2 هو معرف الخلية لعمود رقم هاتفك.اسحب الخلية الجديدة إلى النهاية.

  2. الآن، إذا قرأت الخلية باستخدام POI، فسوف تقرأ الصيغة بدلاً من القيمة المحسوبة.الآن قم بما يلي:

  3. أضف عمودًا آخر

  4. حدد العمود الكامل الذي تم إنشاؤه في الخطوة 1.واختر تحرير->نسخ

  5. انتقل إلى الخلية العلوية للعمود الذي تم إنشاؤه في الخطوة 3.وحدد تحرير->لصق خاص

  6. في النافذة المفتوحة، حدد زر الاختيار "القيم".

  7. حدد "موافق"

  8. اقرأ الآن باستخدام POI API...بعد القراءة في جافا ...فقط قم بإزالة الحرف الأول أي."!"

لقد واجهت أيضًا مشكلة مماثلة في مجموعة بيانات مكونة من آلاف الأرقام وأعتقد أنني وجدت طريقة بسيطة لحلها.كنت بحاجة إلى إدراج الفاصلة العليا قبل الرقم بحيث يرى استيراد قاعدة البيانات المنفصلة دائمًا الأرقام كنص.قبل ذلك، سيتم استيراد الرقم 8 كـ 8.0.

حل:

  • احتفظ بجميع التنسيقات كـ عام.
  • هنا أفترض أن الأرقام مخزنة في العمود A بدءًا من الصف 1.
  • ضع "" في العمود B وانسخ أي عدد من الصفوف حسب الحاجة.لا يظهر أي شيء في ورقة العمل ولكن النقر على الخلية يمكنك رؤية الفاصلة العليا في شريط الصيغة.
  • في العمود ج:=ب1&أ1.
  • حدد جميع الخلايا الموجودة في العمود C وقم بلصق خاص في العمود D باستخدام خيار القيم.

يا المعزوفة جميع الأرقام ولكن تخزينها كنص.

تقوم getStringCellValue بإرجاع NumberFormatException إذا كان نوع الخلية رقميًا.إذا كنت لا تريد تغيير نوع الخلية إلى سلسلة، فيمكنك القيام بذلك.

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

تشير العديد من هذه الإجابات إلى وثائق وفئات النقاط المهمة القديمة.في أحدث نقطة اهتمام 3.16، الخلية مع أنواع int تم إهماله

Cell.CELL_TYPE_STRING

enter image description here

بدلا من ذلك تعداد نوع الخلية ممكن استخدامه.

CellType.STRING 

فقط تأكد من تحديث pom الخاص بك باستخدام تبعية poi بالإضافة إلى تبعية poi-ooxml إلى الإصدار 3.16 الجديد وإلا فسوف تستمر في الحصول على الاستثناءات.إحدى ميزات هذا الإصدار هي أنه يمكنك تحديد نوع الخلية في وقت إنشاء الخلية مما يلغي جميع الخطوات الإضافية الموضحة في الإجابات السابقة:

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

أفضل الذهاب مسار فيل الجواب أو Vinayak Dornala ، لسوء الحظ أنها تنفذ أدائي الآن بكثير.ذهبت HACKY حل ضمني الصب:

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

أنا لا أقترح عليك أن تفعل هذا ، وضعي عملت بسبب طبيعة كيفية عمل النظام و كان موثوق الملف المصدر.

حاشية:numericColumn هو الباحث الذي تم إنشاؤه من قراءة رأس ملف معالجتها.

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());
        }

لقد حاولت هذا وعملت بالنسبة لي

واجهنا نفس المشكلة وأجبرنا مستخدمينا على تنسيق الخلايا كـ "نص" قبل إدخال القيمة.بهذه الطريقة يقوم Excel بتخزين الأرقام الزوجية بشكل صحيح كنص.إذا تم تغيير التنسيق بعد ذلك، يقوم Excel فقط بتغيير طريقة عرض القيمة ولكنه لا يغير طريقة تخزين القيمة إلا إذا تم إدخال القيمة مرة أخرى (على سبيل المثال.عن طريق الضغط على العودة عندما تكون في الخلية).

تتم الإشارة إلى ما إذا كان Excel قد قام بتخزين القيمة كنص بشكل صحيح أم لا من خلال المثلث الأخضر الصغير الذي يعرضه Excel في الزاوية العلوية اليسرى من الخلية إذا كان يعتقد أن الخلية تحتوي على رقم ولكن تم تنسيقها كنص.

هل تتحكم في ورقة عمل Excel بأي حال من الأحوال؟هل هناك قالب لدى المستخدمين لإعطائك المدخلات؟إذا كان الأمر كذلك، فيمكنك الحصول على تعليمات برمجية لتنسيق خلايا الإدخال نيابةً عنك.

يبدو أن هذا لا يمكن القيام به في الإصدار الحالي من POI، استنادًا إلى حقيقة أن هذا الخطأ:

https://issues.Apache.org/bugzilla/show_bug.cgi?id=46136

لا تزال معلقة.

cell.setCellType(Cell.CELL_TYPE_STRING);يعمل بشكل جيد بالنسبة لي

يلقي إلى int ثم يفعل .toString().إنه قبيح لكنه يعمل.

لقد كان هذا مثاليًا بالنسبة لي.

Double legacyRow = row.getCell(col).getNumericCellValue();
String legacyRowStr = legacyRow.toString();
if(legacyRowStr.contains(".0")){
    legacyRowStr = legacyRowStr.substring(0, legacyRowStr.length()-2);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top