【问题标题】:Storing Phone Numbers in Microsoft Excel XSSF using Apache POI使用 Apache POI 在 Microsoft Excel XSSF 中存储电话号码
【发布时间】:2014-11-06 20:32:04
【问题描述】:

我有一个电话号码作为字符串存储在 Excel 中,Excel 文件已成功创建并且数据没有错误,但每个电话号码旁边都有一个“数字存储为文本”错误。

我在网上看到我应该使用 excel 中包含的特殊电话号码格式或自定义 000-000-0000 格式。我可以使用 excel 程序设置这些,但不能从我的 Java 代码中设置。


我四处寻找有关 setCellType 和 DataFormat 的信息,但我认为 CellType 必须是 String,而且我看不出如何将 DataFormat 用于除日期之外的任何内容。

我也看过 DataFormatter,但我不明白如何使用它来存储数据。看起来它只是为了帮助读取数据。 http://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/DataFormatter.html


我该如何执行以下任一操作?

1) 将单元格标记为“忽略错误”,以忽略“数字存储为文本”错误
2) 利用内置的 Excel 单元格格式“特殊> 电话号码”

对于 1) 似乎有一个标志通过保存和关闭文件持续存在,我不知道如何使用 POI 编辑或查看它。有一篇关于它的帖子:

excel 文档的第 669 页和第 670 页涵盖了 FeatFormulaErr2,它是举行 在 FeatRecord 共享功能中,理论上允许您存储 事实上,单元格区域应该忽略“数字作为文本”

我们还有两个测试文件,一个带有警告,一个带有警告 关闭 - 46136-NoWarnings.xls 和 46136-WithWarnings.xls 。我没有创造 但是他们!

尼克 http://mail-archives.apache.org/mod_mbox/poi-user/201003.mbox/%3C27823222.post@talk.nabble.com%3E

看来这可以在 VBA 中使用cell.Errors.Item(xlNumberAsText).Ignore = True 完成,但似乎没有 POI 的等价物

【问题讨论】:

  • 你想要数字还是000-000-0000这种格式?
  • 理想的标准 excel 电话号码格式:“(###) ###-####”。数字似乎不是去这里的方式,因为电话号码实际上是一个字符串(从不进行代数操作)
  • 同意。但将其设为数字​​可确保您只在电话字段中输入数字而不是字母
  • 我可以在我的 Java 代码中测试这一点,我宁愿一个字母出现在输入错误的数字中,也不愿通过将字符串单元格更改为数字单元格来破坏整个数字
  • 写你的 1) 选项:这似乎是定期从 Apache POI 请求的,但还不支持,afaict。请参阅this answer 了解更多信息。

标签: java excel apache-poi openxml vba


【解决方案1】:

我已经想出了如何实现#2)利用内置的Excel单元格格式“特殊>电话号码”

Excel 中的电话号码存储为CELL_TYPE_NUMERIC,而不是CELL_TYPE_STRING

try {
    row.createCell(0).setCellValue(Long.parseLong(aNumericOnlyPhoneNumberString));
} catch (NumberFormatException e) {
    row.createCell(0);
}
CellStyle phoneNumberStyle = wb.createCellStyle();
phoneNumberStyle.setDataFormat(wb.createDataFormat().getFormat("(000) 000-0000"));
row.getCell(0).setCellStyle(phoneNumberStyle);

【讨论】:

    【解决方案2】:

    我不确定您是否在写入 excel 之前进行了数据类型转换。也许你可以使用这样的东西:

    if(cellData.getCellType() == 1)
        cell.setCellValue((String)cellData.getData());
    else if(cellData.getCellType() == 0)
        cell.setCellValue(((Integer)cellData.getData()).intValue());
    

    【讨论】:

    • 单元格数据将始终是 10 位数字字符字符串,并且将始终写入新文件,因此是我在创建时设置类型的新单元格。
    • 建议您将其转换为数字列,或者如果您想将其保留为字符串,则在写入 excel (000)000 000 之前添加括号
    【解决方案3】:

    嘿,试试下面给出的代码-

    @Test
    public void writeToExcel() {
        //Blank workbook
        XSSFWorkbook workbook = new XSSFWorkbook(); 
    
        //Create a blank sheet
        XSSFSheet sheet = workbook.createSheet("Employee Data");
    
        //This data needs to be written (Object[])
        Map<String, Object[]> data = new TreeMap<String, Object[]>();
        data.put("1", new Object[] {"ID", "NAME", "PHONE"});
        data.put("2", new Object[] {1, "Amit", "9865321425"});
        data.put("3", new Object[] {2, "Lokesh","9562264578"});
        data.put("4", new Object[] {3, "John", "9458262145"});
    
    
        //Iterate over data and write to sheet
        Set<String> keyset = data.keySet();
        int rownum = 0;
        for (String key : keyset)
        {
            Row row = sheet.createRow(rownum++);
            Object [] objArr = data.get(key);
            int cellnum = 0;
            for (Object obj : objArr)
            {
               Cell cell = row.createCell(cellnum++);
               if(obj instanceof String)
                    cell.setCellValue((String)obj);
                else if(obj instanceof Integer)
                    cell.setCellValue((Integer)obj);
            }
        }
        try
        {
            //Write the workbook in file system
            FileOutputStream out = new FileOutputStream(new File("D:/writeTest.xlsx"));
            workbook.write(out);
            out.close();
            System.out.println("writeTest.xlsx written successfully on disk.");
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
        }
    }
    

    默认情况下,excel 的单元格类型是字符串。如果您想以数字格式存储电话号码,则必须将单元格类型设置为数字。

               if(obj instanceof String)
                    cell.setCellValue((String)obj);
                else if(obj instanceof Integer){
                   // set cell format to numeric
                    cell.setCellType(Cell.CELL_TYPE_NUMERIC);
                    cell.setCellValue((Integer)obj);
                }
    

    在读取 excel 文件时,请记住您正在读取字符串类型单元格数据或数字类型单元格数据的一件事。

    要读取字符串类型的单元格数据,请使用代码 as-

    cell.getStringCellValue();
    

    并读取数字单元格类型数据--

    cell.getNumericCellValue();
    

    【讨论】:

    • 虽然这是如何写入 excel 文件的一个很好的例子,但它并没有回答我的问题。您将未格式化的数字作为字符串获得,并且它们旁边也有“数字存储为文本”错误
    • 我说的是 MS Excel 中的“数字存储为文本”xlNumberAsText 错误,而不是 Java 中的异常。我以编程方式读写多种单元格类型没有问题。
    【解决方案4】:

    完美地尝试它的工作。 这是读取excel xlsx格式并将所有数据存储在数组列表中的功能..

         public ArrayList Xreadexcel(String file) {        
        boolean f = false;
        ArrayList arraycontainer = new ArrayList();
        try {
            FileInputStream myInput = new FileInputStream(file);
            XSSFWorkbook workbook = new XSSFWorkbook(file);
            XSSFSheet sheet = workbook.getSheetAt(0);
            int rowStart = sheet.getFirstRowNum();
            int rowEnd = sheet.getLastRowNum() + 1;
            int count = workbook.getNumberOfSheets();
            if (count > 1) {
                System.out.println("Only one Sheet Allowed");
            } else {
                for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) {
                    Row row = sheet.getRow(rowNum);
                    int lastColumn = row.getLastCellNum();
                    ArrayList arraylist = new ArrayList();
                    int cn = 0;
                    for (cn = 0; cn < lastColumn + 1; cn++) {
                        Cell cell = row.getCell(cn, Row.RETURN_NULL_AND_BLANK);
                        if ((cell == null) || (cell.equals("")) || (cell.getCellType() == cell.CELL_TYPE_BLANK)) {
                            arraylist.add("");
                        } else {
                            cell.setCellType(Cell.CELL_TYPE_STRING);
                            arraylist.add(cell);
                        }
                    }
                    arraycontainer.add(arraylist);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return arraycontainer;
    }
    

    【讨论】:

    • 这没有帮助。问题中暗示了基本交互的知识。另外,为什么将您的纸张数限制为 1?我的特定用例有 3 张纸;)
    • k 发送您的用例,我将发送完整功能。在这种情况下,您只问如何存储电话号码,以前的功能就足够了。 (只需将所有单元格转换为字符串格式,然后读取它。我检查了我的函数它的工作完美)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    • 1970-01-01
    • 2016-10-26
    • 1970-01-01
    相关资源
    最近更新 更多