Làm cách nào để đặt giá trị ô thành Ngày và áp dụng định dạng ngày mặc định của Excel?


101

Tôi đã sử dụng Apache POI một thời gian để đọc các tệp Excel 2003 hiện có theo chương trình. Bây giờ tôi có một yêu cầu mới là tạo toàn bộ tệp .xls trong bộ nhớ (vẫn sử dụng Apache POI) và sau đó ghi chúng vào một tệp ở cuối. Vấn đề duy nhất cản trở tôi là việc xử lý các ô có ngày tháng.

Hãy xem xét đoạn mã sau:

Date myDate = new Date();
HSSFCell myCell;
// code that assigns a cell from an HSSFSheet to 'myCell' would go here...
myCell.setCellValue(myDate);

Khi tôi ghi sổ làm việc chứa ô này ra tệp và mở nó bằng Excel, ô được hiển thị dưới dạng số. Có, tôi nhận ra rằng Excel lưu trữ 'ngày tháng' của nó dưới dạng số ngày kể từ ngày 1 tháng 1 năm 1900 và đó là số trong ô biểu thị.

HỎI: Tôi có thể sử dụng lệnh gọi API nào trong POI để thông báo rằng tôi muốn áp dụng định dạng ngày mặc định cho ô ngày của mình?

Lý tưởng nhất là tôi muốn ô bảng tính được hiển thị với cùng một định dạng ngày mặc định mà Excel sẽ gán nó nếu người dùng đã mở bảng tính trong Excel theo cách thủ công và nhập vào một giá trị ô mà Excel nhận ra là một ngày.

Câu trả lời:


172

http://poi.apache.org/spreadsheet/quick-guide.html#CreateDateCells

CellStyle cellStyle = wb.createCellStyle();
CreationHelper createHelper = wb.getCreationHelper();
cellStyle.setDataFormat(
    createHelper.createDataFormat().getFormat("m/d/yy h:mm"));
cell = row.createCell(1);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);

21
Cảm ơn ninja, điều này làm việc cho tôi. Một nhận xét cho những người khác cần làm điều này. Có một lớp POI có tên BuiltinFormatsliệt kê tất cả các định dạng chuẩn (không chỉ định dạng ngày tháng) mà Excel biết. Tôi đang gắn bó với một trong những thứ đó để sử dụng làm tham số của mình cho getFormat()phương pháp được hiển thị trong đoạn mã ở trên.
Jim Tough

Phần quan trọng là trong các nhận xét của liên kết: chúng tôi định dạng ô thứ hai là ngày (và giờ). Điều quan trọng là phải tạo kiểu ô mới từ sổ làm việc, nếu không bạn có thể sửa đổi kiểu được tạo sẵn và ảnh hưởng không chỉ đến ô này mà còn các ô khác.
CGK

Cảm ơn, @ninja. Bạn có biết tại sao lại getCreationHelper()cần không? Tôi đang làm việc với Mule ngay bây giờ để tạo tệp đầu ra Excel và tôi thực sự có thể sử dụng createDataFormat()mà không cần trình trợ giúp tạo và tạo tệp Excel trong thử nghiệm của mình. Có một nhược điểm khi không sử dụng nó? Cảm ơn!
Rashiki

@Rashiki Câu trả lời này đã được đăng cách đây 6 năm. Tôi đoán rằng API của Apache POI đã thay đổi trong thời gian này. Câu trả lời của tôi cho câu hỏi của bạn là 'Không, không có nhược điểm (nếu nó hoạt động như mong đợi)'
ninja

Tôi không thấy bất kỳ định dạng nào cho mm/dd/yyyy. Khi tôi sử dụng bất kỳ định dạng nào khác, excel hiển thị lỗi File error, some number formats may have been lost, nó hiển thị Datekiểu trong excel. Tôi không có manh mối làm thế nào điều này có thể được sửa chữa.
akash

24

Để đặt thành loại Excel mặc định Ngày (được mặc định thành ngôn ngữ cấp hệ điều hành / -> tức là xlsx sẽ trông khác khi được mở bởi người Đức hoặc người Anh / và được gắn cờ hoa thị nếu bạn chọn nó trong bộ chọn định dạng ô của Excel), bạn nên:

    CellStyle cellStyle = xssfWorkbook.createCellStyle();
    cellStyle.setDataFormat((short)14);
    cell.setCellStyle(cellStyle);

Tôi đã làm điều đó với xlsx và nó hoạt động tốt.


2
Hoàn toàn đồng ý về bình luận của fiffy. Tôi chỉ có một câu hỏi. Đâu là cách tiếp cận lí tưởng nhất. Dựa vào giá trị ngắn dataFormat (14) hoặc giá trị chuỗi ("m / d / yy"). Giá trị nào thực sự là hằng số mô tả định dạng ngày chuẩn trong Excel? DataFormat.getFormat () có cả với chuỗi và với giá trị ngắn là tham số.
Miklos Krivan

Miklos, tôi không biết giải pháp giá trị chuỗi hoạt động như thế nào. Tôi rất vui nếu ai đó có thể phản hồi cho dù điều đó cũng đang hiển thị "định dạng ngày mặc định khác dựa trên ngôn ngữ" trong Excels với các ngôn ngữ khác nhau.
BlondCode

13

Ví dụ này để làm việc với các loại tệp .xlsx. Ví dụ này đến từ trang .jsp được sử dụng để tạo bảng tính .xslx.

import org.apache.poi.xssf.usermodel.*; //import needed

XSSFWorkbook  wb = new XSSFWorkbook ();  // Create workbook
XSSFSheet sheet = wb.createSheet();      // Create spreadsheet in workbook
XSSFRow row = sheet.createRow(rowIndex); // Create the row in the spreadsheet


//1. Create the date cell style
XSSFCreationHelper createHelper = wb.getCreationHelper();
XSSFCellStyle cellStyle         = wb.createCellStyle();
cellStyle.setDataFormat(
createHelper.createDataFormat().getFormat("MMMM dd, yyyy")); 

//2. Apply the Date cell style to a cell

//This example sets the first cell in the row using the date cell style
cell = row.createCell(0);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);

1

Tôi viết câu trả lời của mình ở đây vì nó có thể hữu ích cho những độc giả khác, những người có thể có yêu cầu hơi khác so với người hỏi ở đây.

Tôi chuẩn bị một mẫu .xlsx; tất cả các ô sẽ được điền ngày tháng, đã được định dạng là ô ngày tháng (sử dụng Excel).

Tôi mở mẫu .xlsx bằng Apache POI và sau đó chỉ cần ghi ngày tháng vào ô và nó hoạt động.

Trong ví dụ bên dưới, ô A1 đã được định dạng từ bên trong Excel với định dạng [$-409]mmm yyyyvà mã Java chỉ được sử dụng để điền ô.

FileInputStream inputStream = new FileInputStream(new File("Path to .xlsx template"));
Workbook wb = new XSSFWorkbook(inputStream);
Date date1=new Date();
Sheet xlsMainTable = (Sheet) wb.getSheetAt(0);
Row myRow= CellUtil.getRow(0, xlsMainTable);
CellUtil.getCell(myRow, 0).setCellValue(date1);

KHI Excel được mở, ngày được định dạng chính xác.


0

Mẫu mã này có thể được sử dụng để thay đổi định dạng ngày. Ở đây tôi muốn thay đổi từ yyyy-MM-dd thành dd-MM-yyyy. Đây poslà vị trí của cột.

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

class Test{ 
public static void main( String[] args )
{
String input="D:\\somefolder\\somefile.xlsx";
String output="D:\\somefolder\\someoutfile.xlsx"
FileInputStream file = new FileInputStream(new File(input));
XSSFWorkbook workbook = new XSSFWorkbook(file);
XSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> iterator = sheet.iterator();
Cell cell = null;
Row row=null;
row=iterator.next();
int pos=5; // 5th column is date.
while(iterator.hasNext())
{
    row=iterator.next();

    cell=row.getCell(pos-1);
    //CellStyle cellStyle = wb.createCellStyle();
    XSSFCellStyle cellStyle = (XSSFCellStyle)cell.getCellStyle();
    CreationHelper createHelper = wb.getCreationHelper();
    cellStyle.setDataFormat(
        createHelper.createDataFormat().getFormat("dd-MM-yyyy"));
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Date d=null;
    try {
        d= sdf.parse(cell.getStringCellValue());
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        d=null;
        e.printStackTrace();
        continue;
    }
    cell.setCellValue(d);
    cell.setCellStyle(cellStyle);
   }

file.close();
FileOutputStream outFile =new FileOutputStream(new File(output));
workbook.write(outFile);
workbook.close();
outFile.close();
}}

0

Để biết chuỗi định dạng được Excel sử dụng mà không cần phải đoán nó: hãy tạo một tệp excel, viết ngày vào ô A1 và định dạng nó theo ý muốn. Sau đó chạy các dòng sau:

FileInputStream fileIn = new FileInputStream("test.xlsx");
Workbook workbook = WorkbookFactory.create(fileIn);
CellStyle cellStyle = workbook.getSheetAt(0).getRow(0).getCell(0).getCellStyle();
String styleString = cellStyle.getDataFormatString();
System.out.println(styleString);

Sau đó, sao chép-dán chuỗi kết quả, xóa dấu gạch chéo ngược (ví dụ: d/m/yy\ h\.mm;@trở thành d/m/yy h.mm;@) và sử dụng nó trong mã http://poi.apache.org/spreadsheet/quick-guide.html#CreateDateCells :

CellStyle cellStyle = wb.createCellStyle();
CreationHelper createHelper = wb.getCreationHelper();
cellStyle.setDataFormat(createHelper.createDataFormat().getFormat("d/m/yy h.mm;@"));
cell = row.createCell(1);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.