Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Apache POI无法检测哈希格式的数字_Java_Excel_Apache Poi - Fatal编程技术网

Java Apache POI无法检测哈希格式的数字

Java Apache POI无法检测哈希格式的数字,java,excel,apache-poi,Java,Excel,Apache Poi,我需要将通过xls/xlsx上传的电话号码读入Java字符串变量,尽可能接近excel文件中显示的内容 所以我填写了这些数据: 如您所见,单元格内的实际值为166609999,其格式为60,因此最后我们看到60166609999出现在单元格上 我想以字符串形式捕获单元格内容60166609999,但到目前为止我只捕获了166609999,有人能告诉我出了什么问题吗 注意:如果我将格式从60更改为6000000000,我可以捕获60166609999而没有任何问题,但是excel是通过公共站点上

我需要将通过xls/xlsx上传的电话号码读入Java字符串变量,尽可能接近excel文件中显示的内容

所以我填写了这些数据:

如您所见,单元格内的实际值为166609999,其格式为60,因此最后我们看到60166609999出现在单元格上

我想以字符串形式捕获单元格内容60166609999,但到目前为止我只捕获了166609999,有人能告诉我出了什么问题吗

注意:如果我将格式从60更改为6000000000,我可以捕获60166609999而没有任何问题,但是excel是通过公共站点上传的,因此我无法强制执行

代码非常简单,如下所示:

Cell cell = getTheCell(); // Got this after reading the sheets and rows
DataFormatter df = new DataFormatter();
String value = df.formatCellValue(cell);
// Here in value
// If format is 600000000, I can get 60166609999 (right)
// If format is 60#######, I get 166609999 (wrong)
我正在使用的库:

poi poi 3.17 poi ooxml 3.17 poi ooxml模式3.17 爪哇7 有人知道我需要做什么才能做对吗


谢谢。

这个问题是多方面的

首先,数字格式60不能使用Java应用。它导致java.lang.IllegalArgumentException:使用的模式60格式错误

但是,如果需要在每个数字前面加上60,那么Excel数字格式\6\0或60应该是可能的,并且应该转换为十进制格式模式“60”。但是ApachePOI的DataFormatter没有,因为它只是从Excel的格式字符串中删除所有引用,这导致60,这也是一种格式错误的模式

问题出在你身上

我在MyDataFormatter中对此进行了如下修补:

如果值199901234位于Excel格式的单元格A1到A4中,则会产生以下输出,如图所示:

Cell A1
Excel's data format string: \60##########
Value using poi's data formatter: using poi's cleanFormatStr: 60########## result: 199901234
Value using my data formatter: using my cleanFormatStr: '6'0########## result: 199901234
Cell A2
Excel's data format string: \60000000000
Value using poi's data formatter: using poi's cleanFormatStr: 60000000000 result: 60199901234
Value using my data formatter: using my cleanFormatStr: '6'0000000000 result: 60199901234
Cell A3
Excel's data format string: "60"#
Value using poi's data formatter: using poi's cleanFormatStr: 60# result: 199901234
Value using my data formatter: using my cleanFormatStr: '60'# result: 60199901234
Cell A4
Excel's data format string: \6\0#
Value using poi's data formatter: using poi's cleanFormatStr: 60# result: 199901234
Value using my data formatter: using my cleanFormatStr: '60'# result: 60199901234

在我看来,这是一个Apache POI bug。您是否有可能编写一个简短的junit单元测试来显示问题,然后在Apache POI bugzilla中打开一个bug?@Gagravarr我已经在这里提交了一个请求,有什么需要修改的吗?非常感谢您为解决此问题所做的努力。我试图消化代码,但根据结果,你是否暗示全球支持60种格式基本上不是一件容易的事情?好消息是我实际上不需要检测小数点和许多其他复杂的格式,所以如果我可以像你那样调用format方法,我想我可以自己复制函数,然后将所有函数替换为“0”,以得到我最终想要的?@Chor Wai-Chun:如前所述,不能使用Java的十进制格式应用数字格式60。但这对我来说也毫无意义。在所有数字前加6,并在数字前加0,长度不超过4位。这意味着什么?Excel的格式为60或\6\0,即:使用我描述的补丁程序,所有数字都可以使用60作为前缀。它实际上对世界其他地方没有意义哈哈,除了马来西亚,我们的国家代码是60,因此我们将其附加在数字的前面以获得国际格式。我无法控制我的用户会采用什么样的格式,但我能做的只是为他们的预测输入添加尽可能多的支持。因此,我想在调用format函数之前将其格式中的替换为“0”是我最好的选择..最后,我复制了整个DataFormatter类,并执行formatStr=formatStr.replace,0;在函数格式getFormatCell cell中,ConditionalFormattingEvaluator cfEvaluator修复了我的问题,谢谢Axel=@Chor Wai Chun:Hm,我认为这不是一种方法,因为它太笼统了。该模式在某些情况下是有意义的,应该与0不同,而不是总是被0替换。例如,0.00表示:如果需要,将千分位分隔符放入,将100格式化为100.00,将1000格式化为1000.00,然后将0000.00,甚至将1格式化为0001.00;-。
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;

import java.io.FileInputStream;

import java.lang.reflect.Method;

class ExcelDataformatterExample {

 public static void main(String[] args) throws Exception {

  Workbook wb  = WorkbookFactory.create(new FileInputStream("ExcelExample.xlsx"));

  DataFormatter df = new DataFormatter();
  MyDataFormatter mydf = new MyDataFormatter();

  Sheet sheet = wb.getSheetAt(0);
  for (Row row : sheet) {
   for (Cell cell : row) {
    if (cell.getCellTypeEnum() == CellType.NUMERIC) {
     CellReference cellRef = new CellReference(row.getRowNum(), cell.getColumnIndex());
     System.out.println("Cell " + cellRef.formatAsString());

     System.out.print("Excel's data format string: ");
     String formatStr = cell.getCellStyle().getDataFormatString();
     System.out.println(formatStr);

     System.out.print("Value using poi's data formatter: ");
     Method cleanFormatForNumber = DataFormatter.class.getDeclaredMethod("cleanFormatForNumber", String.class); 
     cleanFormatForNumber.setAccessible(true); 
     String cleanFormatStr = (String)cleanFormatForNumber.invoke(df, formatStr);
     System.out.print("using poi's cleanFormatStr: ");
     System.out.print(cleanFormatStr + " result: ");
     String value = df.formatCellValue(cell);
     System.out.println(value);

     System.out.print("Value using my data formatter: ");
     cleanFormatForNumber = MyDataFormatter.class.getDeclaredMethod("cleanFormatForNumber", String.class); 
     cleanFormatForNumber.setAccessible(true); 
     cleanFormatStr = (String)cleanFormatForNumber.invoke(mydf, formatStr);
     System.out.print("using my cleanFormatStr: ");
     System.out.print(cleanFormatStr + " result: ");
     value = mydf.formatCellValue(cell);
     System.out.println(value);

    }
   }
  }
  wb.close();

 }

}
Cell A1
Excel's data format string: \60##########
Value using poi's data formatter: using poi's cleanFormatStr: 60########## result: 199901234
Value using my data formatter: using my cleanFormatStr: '6'0########## result: 199901234
Cell A2
Excel's data format string: \60000000000
Value using poi's data formatter: using poi's cleanFormatStr: 60000000000 result: 60199901234
Value using my data formatter: using my cleanFormatStr: '6'0000000000 result: 60199901234
Cell A3
Excel's data format string: "60"#
Value using poi's data formatter: using poi's cleanFormatStr: 60# result: 199901234
Value using my data formatter: using my cleanFormatStr: '60'# result: 60199901234
Cell A4
Excel's data format string: \6\0#
Value using poi's data formatter: using poi's cleanFormatStr: 60# result: 199901234
Value using my data formatter: using my cleanFormatStr: '60'# result: 60199901234