How can I set Date value into cell - java

Following is my code:
String monthEndDate = "31-Dec-17";
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy",java.util.Locale.ENGLISH);
XSSFCell updateDateCell = sheet.getRow(rownumber).getCell(15);
XSSFCellStyle cellStyle = (XSSFCellStyle)updateDateCell.getCellStyle();
CreationHelper createHelper = wb.getCreationHelper();
cellStyle.setDataFormat(
createHelper.createDataFormat().getFormat("dd-MMM-yy"));
Date updateDate = sdf.parse(monthEndDate);
updateDateCell.setCellValue(updateDate);
updateDateCell.setCellStyle(cellStyle);
It is setting numeric value 43100.0

I suspect your problem is that you are getting the CellStyle via Cell.getCellStyle and then you are overwriting that CellStyle.
CellStyles are in Excel defined on Workbook level. That means, not each cell has it's own cell style but cells share cell styles defined on workbook level.
So if you do the getting the CellStyle via Cell.getCellStyle and then overwriting that CellStyle multiple times then only the last overwriting will be active. So I suspect, your complete code overwrites the same cell style, gotten from another cell, with another number format after you have overwritten it with the date number format.
The easy conclusion could be to really give each cell it's own cell style. But this is also wrong since there is a limit number of cell styles in a workbook. So we need
Having as much own cell styles as needed.
Having as much cell styles shared as possible.
To achieve this CellUtil can be used in apache poi. This provides methods only to create a new cell style if there is not already the same cell style defined in the workbook and simply to use that cell style if there is already the same cell style defined in the workbook.
Example:
import java.io.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.CellUtil;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.HashMap;
public class ExcelSetDateValue {
public static void main(String[] args) throws Exception {
XSSFWorkbook wb = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream("ExcelTest.xlsx"));
//possiby we need data formats
DataFormat dataFormat = wb.createDataFormat();
//get sheet and set row number
XSSFSheet sheet = wb.getSheetAt(0);
int rownumber = 3;
//get the date
String monthEndDate = "31-Dec-17";
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy", java.util.Locale.ENGLISH);
Date updateDate = sdf.parse(monthEndDate);
//set date as cell value
XSSFCell updateDateCell = sheet.getRow(rownumber).getCell(15);
updateDateCell.setCellValue(updateDate);
//use CellUtil to set the CellStyleProperties
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(CellUtil.DATA_FORMAT, dataFormat.getFormat("dd-MMM-yy"));
CellUtil.setCellStyleProperties(updateDateCell, properties);
wb.write(new FileOutputStream("ExcelTestNew.xlsx"));
wb.close();
}
}

Add updateDateCell = Format(updateDateCell, "dd-MMM-yyyy") at the end of your code.
You should get 31-Dec-2017.

This is an example which I already have for formatting date, you can reuse the part of it ( I marked the relevant lines of code). It's tested and working fine, if any issue let me know.
//UPDATE
Please see Axel Richter's answer https://stackoverflow.com/a/47920182/1053496 for the correct answer. In my example, I'm storing date as String instead of Date object which is not the recommended way
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.xssf.usermodel.*;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class WriteExcelBasic {
public static void main(String[] args) throws IOException {
String excelFileName = "/Users/home/Test3.xls";
FileOutputStream fos = new FileOutputStream(excelFileName);
XSSFWorkbook wb = new XSSFWorkbook();
XSSFCellStyle style = wb.createCellStyle();
XSSFSheet sheet = wb.createSheet("sheet");
XSSFFont urlFont = wb.createFont();
style.setFont(urlFont);
String monthEndDate = "31-Dec-17";
DataFormat df = wb.createDataFormat(); //these 3 lines are enough
short dateFormat = df.getFormat("dd-MMM-yy"); // 2nd
style.setDataFormat(dateFormat); // 3rd
for (int r = 0; r < 1; r++) {
XSSFRow row = sheet.createRow(r);
row.setHeight((short) -1);
for (int c = 0; c < 3; c++) {
XSSFCell cell = row.createCell(c);
String ss = "31-Dec-17";
cell.setCellValue(ss);
style.setWrapText(true);
cell.setCellStyle(style);
}
}
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
wb.write(baos);
byte[] myByteArray = baos.toByteArray();
fos.write(myByteArray);
fos.flush();
}
finally {
wb.close();
fos.close();
}
}
}

Related

Unable to format Date cell in exported excel using Apache POI

I am using Workbook wb = new XSSFWorkbook();for exporting an excel sheet, which contains a column which is a DATE. Even after setting the style as DATE, the column is shown as GENERAL in the Excel sheet.
Here is my piece of code for cell creation
Workbook wb = new XSSFWorkbook();
int rowValue = 1; CellStyle cellStyleOfHeaderRow = wb.createCellStyle(); CellStyle style = wb.createCellStyle();
Font fontOfCell = initializeCellFont(wb, cellStyleOfHeaderRow); initializeCellBorders(cellStyleOfHeaderRow); initializeCellFillOptions(cellStyleOfHeaderRow);
initializeCellBorders(style); CreationHelper createHelper = wb.getCreationHelper();
short dateFormat = createHelper.createDataFormat().getFormat("yyyy-MM-dd-hh.mm.ss");
style.setDataFormat(dateFormat);
After opening the exported excel, when I try to change the format of the date column from GENERAL to DATE, I am unable to do so.
Could you suggest some piece of code or any solution to this?
I suspect your data 2016-01-28 12:06:00.0, ... are Strings rather than Dates. If you set strings in a Excel cell, then the cell cannot be a date cell. The cell value must be a numeric value to let the cell be a date cell. So you needs converting that Strings to Dates before setting the cell value. Then set that Date as the cell value.
Using current apache poi 4.1.2 this can be done using java.time.format.DateTimeFormatter and java.time.LocalDateTime since there is Cell.setCellValue(java.time.LocalDateTime value) now.
Up to apache poi 3.17 it can be done using java.text.SimpleDateFormat and java.util.Date. Cell.setCellValue(java.util.Date value) is the setCellValue method used then.
Complete example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
class CreateExcelDateCells {
public static void main(String[] args) throws Exception {
try (Workbook workbook = new XSSFWorkbook();
FileOutputStream fileout = new FileOutputStream("Excel.xlsx") ) {
String[][] data = new String[][] {
new String[] {"Date"},
new String[] {"2016-01-28 12:06:00.0"},
new String[] {"2016-01-27 08:29:00.0"},
new String[] {"2016-01-18 21:37:00.0"}
};
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S", Locale.US);
//SimpleDateFormat simpleDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S", Locale.US); // up to apache poi 3.17
CellStyle dateCellStyle = workbook.createCellStyle();
dateCellStyle.setDataFormat(workbook.createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss"));
Sheet sheet = workbook.createSheet();
for (int r = 0; r < data.length; r++) {
Row row = sheet.createRow(r);
Cell cell = row.createCell(0);
if (r == 0) {
cell.setCellValue(data[r][0]); // String cell value
} else {
cell.setCellValue(LocalDateTime.parse(data[r][0], dateTimeFormatter)); // Date cell value
//cell.setCellValue(simpleDateFormatter.parse(data[r][0])); // Date cell value up to apache poi 3.17
cell.setCellStyle(dateCellStyle);
}
}
sheet.autoSizeColumn(0);
workbook.write(fileout);
}
}
}

POI - How do I remove a particular String values in Excel?

I've been using Apache POI for display print files .xls format programmatically. The only problem standing in my way,that is i have date format in the following manner in the excel which changed to string format:
screenshot - excel file,
this above excel image contains a (') this string
relevant code here,
cell = row.createCell((short)0);
cell.setCellValue(form.getAdd2());// Date
cell.setCellStyle(cellStyle2);
What exact type returns form.getAdd2()? I suspect it is a String rather than a Date. If so you needs converting that String to a Date before setting the cell value. Then set that Date as the cell value.
Using current apache poi 4.1.2 this can be done using java.time.format.DateTimeFormatter and java.time.LocalDate since there is Cell.setCellValue(java.time.LocalDate value) now.
Up to apache poi 3.17 it can be done using java.text.SimpleDateFormat and java.util.Date. Cell.setCellValue(java.util.Date value) is the setCellValue method used then.
Complete example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.util.List;
import java.util.ArrayList;
import java.time.format.DateTimeFormatter;
import java.time.LocalDate;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
class CreateExcelSetDateCellValue {
public static void main(String[] args) throws Exception {
List<Form> forms = new ArrayList<Form>();
Form f;
f = new Form(); f.setAdd2("10-Jan-2020"); forms.add(f);
f = new Form(); f.setAdd2("1-Jan-2020"); forms.add(f);
f = new Form(); f.setAdd2("12-Jan-2020"); forms.add(f);
f = new Form(); f.setAdd2("19-Jan-2020"); forms.add(f);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("d-MMM-yyyy", Locale.US);
//SimpleDateFormat simpleDateFormatter = new SimpleDateFormat("dd-MMM-yyyy", Locale.US); // up to apache poi 3.17
Workbook workbook = new XSSFWorkbook();
CellStyle cellStyle2 = workbook.createCellStyle();
cellStyle2.setDataFormat(workbook.createDataFormat().getFormat("d-MMM-yyyy"));
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("DateString");
cell = row.createCell(1);
cell.setCellValue("Date");
int r = 1;
for (Form form : forms) {
row = sheet.createRow(r);
cell = row.createCell(0);
cell.setCellValue(form.getAdd2());// String
cell.setCellStyle(cellStyle2);
cell = row.createCell(1);
cell.setCellValue(LocalDate.parse(form.getAdd2(), dateTimeFormatter));// Date
//cell.setCellValue(simpleDateFormatter.parse(form.getAdd2()));// Date up to apache poi 3.17
cell.setCellStyle(cellStyle2);
r++;
}
sheet.setColumnWidth(0, 15*256);
sheet.setColumnWidth(1, 15*256);
FileOutputStream out = new FileOutputStream("Excel.xlsx");
workbook.write(out);
out.close();
workbook.close();
}
static class Form {
private String add2 = "";
public void setAdd2(String add2) {
this.add2 = add2;
}
public String getAdd2() {
return this.add2;
}
}
}
Column A contains the dates as Strings and shows your issue. Column B contains really dates.

POI and setting cells to VerticalAlignment.MIDDLE

Hey all I am trying to get my cell to vertical line instead of just being aligned by the left side using POI.
This is my java code:
static CellStyle headerCellStyle = workbook.createCellStyle();
headerCellStyle = workbook.createCellStyle();
Row headerRow = null;
sheet = workbook.createSheet("String " + sheetname);
headerCellStyle.setWrapText(true);
headerCellStyle.setAlignment(HorizontalAlignment.LEFT);
headerCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
headerCellStyle.setVerticalAlignment(VerticalAlignment.MIDDLE);
// Create a Row
headerRow = sheet.createRow(0);
However, the line headerCellStyle.setVerticalAlignment(VerticalAlignment.MIDDLE); has an error of:
The method setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment) in the type CellStyle is not applicable for the arguments (org.apache.poi.sl.usermodel.VerticalAlignment)
How can i go about getting this to work if I have already defined it as an static CellStyle headerCellStyle = workbook.createCellStyle();?
Changing to SS does not seem to have the "middle" option?
This is the difference within excel for those 2 types:
The default way:
The Middle way (the way I am wanting):
The Center way:
Your second image (the way you want) shows CellStyle.setVerticalAlignment(VerticalAlignment.CENTER). Your third image shows CellStyle.setAlignment(HorizontalAlignment.CENTER).
There is a difference between setVerticalAlignment(VerticalAlignment.CENTER) and setAlignment(HorizontalAlignment.CENTER). The first sets vertical alignment to center (aka middle). The second sets horizontal alignment to center.
Complete Example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
class CreateExcelVerticalAlignment {
public static void main(String[] args) throws Exception {
// try (Workbook workbook = new XSSFWorkbook();
// FileOutputStream fileout = new FileOutputStream("Excel.xlsx") ) {
try (Workbook workbook = new HSSFWorkbook();
FileOutputStream fileout = new FileOutputStream("Excel.xls") ) {
CellStyle headerCellStyle = workbook.createCellStyle();
headerCellStyle = workbook.createCellStyle();
headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
Sheet sheet = workbook.createSheet();
sheet.setColumnWidth(0, 20*256);
Row row = sheet.createRow(0);
row.setHeightInPoints(40);
Cell cell = row.createCell(0);
cell.setCellStyle(headerCellStyle);
cell.setCellValue("1082192560 1868");
workbook.write(fileout);
}
}
}
Result:

Apache-poi decimal formatting is being applied only after selection

Could you please suggest on next case?
I`ve set up dataformat and cell type ("#,###.00", NUMERIC)
(I want thounsand separator plus two decimal numbers)
It works as I expected but to have formatted cells I need to select them first
Before selection data looks not formatted
In other words I have to select cell so that it is formatted, otherwise it stays without any formatting
CellStyle style = workbook.createCellStyle();
style.setAlignment(HorizontalAlignment.RIGHT);
style.setLocked(locked);
style.setDataFormat(workbook.createDataFormat().getFormat("#,###.00"));
cell.setCellStyle(style);
cell.setCellType(CellType.NUMERIC);
cell.setCellValue(<big decimal value>.toString());
Simply do not set cell value as string if you need a numeric cell value. If you set cell value as String, then the cell type also will be string. This is independent of setting CellType before setting cell value. While setting a String cell value the type changes to string always.
See API documentation which shows that Cell.setCellType is deprecated and what Cell.setCellValue methods are possible.
You needs setting a double cell value if cell shall have numeric content.
Example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.math.BigDecimal;
import java.util.Random;
class CreateExcelCellNumberFormat {
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(workbook.createDataFormat().getFormat("#,###.00"));
Sheet sheet = workbook.createSheet();
for (int r = 0; r < 10; r++) {
Cell cell = sheet.createRow(r).createCell(0);
cell.setCellStyle(style);
BigDecimal bigDecimal = new BigDecimal(new Random().nextDouble() * 10000000000000d);
cell.setCellValue(bigDecimal.doubleValue());
}
sheet.setColumnWidth(0, 25 * 256);
workbook.write(fileout);
}
}
}

apache poi reuse the style by changing back ground color

I am using apache poi 3.17 to create an Excel file.
Different columns may contain different type of values and I would like to style them accordingly. Rather than creating the style every time, I try to use the same style( to avoid the unnecessary object creation) and change the necessary properties. For eg: some cell I want to make italics, some bold, some with yellow color, some with underline etc..
But to my surprise, I found that style is not changing.
Below is a sample code where I try to set row 1 with 'yellow color' and rest with 'red color' but in the generated excel all rows are red.
import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.xssf.usermodel.*;
import java.awt.*;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class WriteExcelBasic {
public static void main(String[] args) throws IOException {
String excelFileName = "/Users/username/Test3.xlsx";
FileOutputStream fos = new FileOutputStream(excelFileName);
XSSFWorkbook wb = new XSSFWorkbook();
XSSFCellStyle style = wb.createCellStyle();
XSSFSheet sheet = wb.createSheet("sheet");
Font urlFont = wb.createFont();
urlFont.setFontHeight((short)(9*20));
style.setFont(urlFont);
for (int r = 0; r < 3; r++) {
XSSFRow row = sheet.createRow(r);
for (int c = 0; c < 3; c++) {
XSSFCell cell = row.createCell(c);
Hyperlink link = wb.getCreationHelper().createHyperlink(HyperlinkType.URL);
String ss = "http://news.google.com/news/headlines?ned=us&hl=en";
link.setAddress(ss);
cell.setHyperlink(link);
cell.setCellValue(ss);
if(r == 1) {
System.out.println("In yellow");
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setFillForegroundColor(new XSSFColor(Color.YELLOW));
} else {
System.out.println("In red");
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setFillForegroundColor(new XSSFColor(Color.RED));
}
cell.setCellStyle(style);
}
}
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
wb.write(baos);
byte[] myByteArray = baos.toByteArray();
fos.write(myByteArray);
fos.flush();
}
finally {
wb.close();
fos.close();
}
}
}
To solve this issue, I could create 2 styles separately and apply them based on the condition but in a practical case I have to create 24 different styles but for that, I have to write so much redundant code.
If I want to create a new style with a different property then I have to create another 24 styles with this new property. Therefore the complexity will go exponentially.
Therefore, can anyone provide some suggestion on this issue?

Categories

Resources