当前位置: 首页 > 知识库问答 >
问题:

POI-Excel之间的转换问题

昌琪
2023-03-14

我正在尝试使用ApachePOI(4.0.1)在Excel工作簿的单元格中节省时间。

我将时间转换成java。util。日期,然后尝试使用组织。阿帕奇。波伊。党卫军。用户模型。DateUtil。getExcelDate方法,然后将其保存在单元格中。

我的发现是,由于时间与大纪元(1899年)在同一年,所以在getExcelDate中有一个硬编码的签入,它禁止将日期转换为1900年之前的年份,阻止我做我想做的事情。

示例应用:

import java.util.Date;
import java.util.stream.DoubleStream;
import org.apache.poi.ss.usermodel.DateUtil;

public class POIQuery {
    public static void main(final String[] args) {
    final String format = "%-20s%-35s%-20s%n"; //$NON-NLS-1$

    System.out.format(format, "Input Excel Date", "Java Date", "Converted Excel Date");

    DoubleStream.of(0, 0.5d, 1.5d).forEach(excelDate -> {
        final Date date = DateUtil.getJavaDate(excelDate);
        System.out.format(format, excelDate, date, DateUtil.getExcelDate(date));
    });
    }
}

输出(注意,根据文档,转换的Excel日期“-1”表示错误)。

Input Excel Date    Java Date                          Converted Excel Date
0.0                 Sun Dec 31 00:00:00 GMT 1899       -1.0                
0.5                 Sun Dec 31 12:00:00 GMT 1899       -1.0                
1.5                 Mon Jan 01 12:00:00 GMT 1900       1.5

在这里你可以看到,我要求的是代表Excel日期“0.5”的Java日期。然后我使用提供的Java日期,但POI说没有对应的Excel日期——尽管我是根据该日期生成的。

我错过什么了吗。。。?

共有1个答案

孟哲
2023-03-14

Excel1900日期系统中的日期值从值0=1900年1月的第0天开始。在此之前没有Exceldate值。

如果在Excel中有以下单元格:

     A                  B
1  Value      Excel date
2      0      01/00/1900 00:00:00
3    0.5      01/00/1900 12:00:00
4      1      01/01/1900 00:00:00
5    1.5      01/01/1900 12:00:00

如果列B中的值与列A中的值相同,但格式为日期,使用数字格式MM/DD/yyyyy hh:MM:ss,您可以看到。

因此,没有Excel日期1899年12月31日。这就是为什么当日期为Java时,DateUtil.getExcelDate(date)失败。

但是DateUtil.getJavaDate(excelDate)返回1899年12月31日,此时excelDate是一个从0.00.999...的双重值。这是因为没有Java日期1月0日1900可能。但是有Excel日期值可能从0.00.999...

换句话说,Excel日期值从0.00.999实际上是Excel中第一个可能的全天之前的时间值,日期为1900年1月1日。它们不是在一天之内,而是在第0天。

自日期值从0.00.999 和转换的Java日期1899年12月31日是特殊情况,可以这样处理。

通过扩展代码:

import java.util.Date;
import java.util.Calendar;
import java.util.stream.DoubleStream;
import org.apache.poi.ss.usermodel.DateUtil;

public class POIQuery {
    public static void main(final String[] args) {
    final String format = "%-20s%-35s%-20s%n"; //$NON-NLS-1$

    System.out.format(format, "Input Excel Date", "Java Date", "Converted Excel Date");

    DoubleStream.of(0, 0.5d, 1d, 1.5d, 44000d, 44000.5d).forEach(excelDate -> {
        final Date date = DateUtil.getJavaDate(excelDate);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        double excelDateFromDate = -1d;
        if (cal.get(Calendar.YEAR) == 1899 && cal.get(Calendar.MONTH) == 11 && cal.get(Calendar.DATE) == 31) {
         cal.add(Calendar.DATE, 1);
         excelDateFromDate = DateUtil.getExcelDate(cal.getTime());
         excelDateFromDate -= 1d; 
        } else {
         excelDateFromDate = DateUtil.getExcelDate(date);
        }
        System.out.format(format, excelDate, date, excelDateFromDate);
    });
    }
}

如果转换的Java日期是1899年12月31日,我们知道这是从Excel转换而来的,那么在将其重新转换为Excel日期值时,首先在使用DateUtil之前添加一天。getExcelDate。所以DateUtil。getExcelDate从1900年1月1日开始转换。然后从DateUtil的结果中减去1。getExcelDate

 类似资料:
  • 我正在使用Apache POI生成excel工作表(. xls格式),并且我使用以下代码片段创建了链接到同一文档/工作簿中不同工作表的超链接。 我正在创建多个工作表,单击超链接后,它会显示相应的工作表。但是,我很难遍历到我用上述代码行创建的不同工作表。我需要用数据库中的数据填充这些工作表,但我不知道如何在这些工作表之间切换。 任何帮助都将不胜感激。如果我的问题有任何问题,请在投票前告诉我。谢谢!

  • 我正在尝试将excel文件转换为XSSFWorkbook,我有大约7000行和大约145列。将excel文件转换为第2行的XSSFWorkbook大约需要15分钟,代码如下:- 我不想向XFFSWorkbook添加7000行,只想在第2行转换时向XFFSWorkbook添加30行? 如果没有,如何减少将excel转换为XSSFWorkbook所需的时间?

  • 了解如何在Java编程中使用POI Excel。 以下是示例 - 如何使用Java创建空白Excel工作表。 如何使用Java将数据写入Excel工作表。 如何使用Java在电子表格中创建不同类型的单元格。 如何使用Java将不同样式应用于电子表格中的单元格。 如何使用Java将字体应用于单元格的内容。 如何使用Java为单元格中的文本设置方向。 如何使用Java向单元格的内容添加超链接。 如何使

  • 不是打印机问题 将生成的excel内容复制到新的excel中时。它的印刷非常完美。 所以一定是代码或者POI出了问题。

  • 问题内容: 我有一个Java程序,它将标头和数据作为输入并生成一个excel文件。 但是,有时当标头值很长且列数更多时,我的Excel工作表往往会变得不必要地变宽。 由于标题的原因,我将不得不向下滚动以查看尾端列的内容。 有没有一种方法可以解决此问题,如果单元格中的内容较大,然后说x值,则自动换行发生并自动调整行高,固定列宽。 我正在寻找的粗略算法是: 如果有人可以指出一些在线示例。 谢谢阅读!

  • 我目前正在开发一个应用程序,用户可以通过十六进制编辑器界面编辑ByteBuffer,也可以通过JTextPane编辑相应的文本。我当前的问题是因为JTextPane需要一个字符串,我需要在显示值之前将ByteBuffer转换为字符串。但是,在转换过程中,无效字符将替换为字符集默认替换字符。这会压缩无效值,因此当我将其转换回字节缓冲区时,无效字符值将替换为默认替换字符的字节值。有没有一种简单的方法可