java - Apache POI:如何根据 Java DateTimeFormatter 设置单元格的 dataFormat
问题描述
我需要使用主机操作系统上指定的格式将日期和时间数据导出到 Excel。
我发现在 Java 中获得这种格式的唯一方法是使用 DateTimeFormatter。然后我需要使用 Apache POI 设置 Excel 单元格的数据格式。我怎么做?
要获取 CellStyle 中方法 setDataFormat 的数据格式,我必须有一个格式字符串(或表示内置类型的短字符串),但我无法从 DateTimeFormatter 中获取字符串模式。有没有办法进行这种转换?
final SXSSFWorkbook workbook;
final CellStyle style;
final DataFormat formatFactory;
style = workbook.createCellStyle();
DateTimeFormatter format = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT); //Format depends on local settings on client machine
style.setDataFormat(formatFactory.getFormat(format)); //Doesn't work
解决方案
可以使用java.text.DateFormat
如下方式实现此要求:
DateFormat format = DateFormat.getDateTimeInstance(
DateFormat.SHORT, DateFormat.SHORT,
Locale.getDefault());
String pattern = ((SimpleDateFormat)format).toPattern();
System.out.println(pattern);
或者java.time.format.DateTimeFormatterBuilder
像这样使用:
String pattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.SHORT, FormatStyle.SHORT,
Chronology.ofLocale(Locale.getDefault()),
Locale.getDefault());
System.out.println(pattern);
在这两种情况下,都需要转换模式以Excel
使用DateFormatConverter,如下所示:
pattern = DateFormatConverter.convert(Locale.getDefault(), pattern);
System.out.println(pattern);
完整示例:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.DateFormatConverter;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.util.Date;
import java.util.Locale;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.FormatStyle;
import java.time.chrono.Chronology;
class CreateExcelCellDateFormat {
public static void main(String[] args) throws Exception {
//Locale.setDefault(new Locale("en", "US"));
System.out.println(Locale.getDefault());
String pattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.SHORT, FormatStyle.SHORT,
Chronology.ofLocale(Locale.getDefault()), Locale.getDefault());
System.out.println(pattern);
/*
DateFormat format = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault());
String pattern = ((SimpleDateFormat)format).toPattern();
System.out.println(pattern);
*/
pattern = DateFormatConverter.convert(Locale.getDefault(), pattern);
System.out.println(pattern);
try (Workbook workbook = new XSSFWorkbook();
FileOutputStream fileout = new FileOutputStream("Excel.xlsx") ) {
CellStyle style = workbook.createCellStyle();
style.setDataFormat(workbook.createDataFormat().getFormat(pattern));
Sheet sheet = workbook.createSheet();
Cell cell = sheet.createRow(0).createCell(0);
cell.setCellStyle(style);
cell.setCellValue(new Date());
sheet.setColumnWidth(0, 25 * 256);
workbook.write(fileout);
}
}
}
但是,如果真正的要求是创建一个Excel
工作簿,该工作簿显示依赖于Excel 应用程序运行的用户区域设置的日期时间值,那么这一切都不是必需的。然后使用BuiltinFormats 0xe, "m/d/yy" 短日期或 0x16, "m/d/yy h:mm" 短日期时间。
例子:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
class CreateExcelCellDateFormatUserLocale {
public static void main(String[] args) throws Exception {
try (Workbook workbook = new XSSFWorkbook();
FileOutputStream fileout = new FileOutputStream("Excel.xlsx") ) {
CellStyle style = workbook.createCellStyle();
//style.setDataFormat((short)14); //0xe, "m/d/yy"
style.setDataFormat((short)22); //0x16, "m/d/yy h:mm"
Sheet sheet = workbook.createSheet();
Cell cell = sheet.createRow(0).createCell(0);
cell.setCellStyle(style);
cell.setCellValue(new java.util.Date());
sheet.setColumnWidth(0, 25 * 256);
workbook.write(fileout);
}
}
}
该代码会生成一个Excel
文件,该文件显示的日期时间与应用程序Excel
运行的语言环境完全一样。对于德国,它显示 dd.MM.yyyy hh:mm。对于美国,它显示 MM/dd/yy h:m AM/PM。对于英国,它显示 dd/MM/yyyy hh:mm。Excel