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

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.

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);
}
}
}

Apache POI: How do I set the dataFormat of a cell based on a Java DateTimeFormatter

I need to export date and time data to Excel, using the format specified on the host OS.
The only way I've found to get this format in Java is by using DateTimeFormatter. I then need to set the data format of the Excel cell using Apache POI. How do I do that?
To get a data format for the method setDataFormat in CellStyle I must have a format string (or a short representing a build in type), but I cannot get a string pattern out of the DateTimeFormatter. Is there any way to make this conversion?
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
This requirement can be achieved using java.text.DateFormat like so:
DateFormat format = DateFormat.getDateTimeInstance(
DateFormat.SHORT, DateFormat.SHORT,
Locale.getDefault());
String pattern = ((SimpleDateFormat)format).toPattern();
System.out.println(pattern);
Or using java.time.format.DateTimeFormatterBuilder like so:
String pattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.SHORT, FormatStyle.SHORT,
Chronology.ofLocale(Locale.getDefault()),
Locale.getDefault());
System.out.println(pattern);
In both cases the pattern needs to be converted for usage in Excel using DateFormatConverter like so:
pattern = DateFormatConverter.convert(Locale.getDefault(), pattern);
System.out.println(pattern);
Complete example:
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);
}
}
}
But if the really requirement is to create a Excel workbook which shows date-time values dependent on the user locale the Excel application runs in, then this all is not necessary. Then do using the BuiltinFormats 0xe, "m/d/yy" for short date or 0x16, "m/d/yy h:mm" for short date-time.
Example:
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);
}
}
}
That code produces a Excel file which shows the date-time exactly as Excel does dependent on the locale the Excel application runs in. For Germany it shows dd.MM.yyyy hh:mm. For US it shows MM/dd/yy h:m AM/PM. For UK it shows dd/MM/yyyy hh:mm.

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);
}
}
}

How can I set Date value into cell

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();
}
}
}

Excel POI API changing cell value

I have to read a excel file and fill some cells with POI API for JAVA. The I write the whole workbook into another. That is actually working.
The problem is that then (once the cells are filled) I have to open the file and click and enter in the cells I've modified in order to refresh the values of the other formula's cells.
The code is like that:
cellHorasPrevistas.setCellValue("01:00:00")
When I enter in the xls file it seems to be a raw String instead of being formatted as "[h]:mm:ss" which was the initial format of the cell.
I have tried to rewrite the format manually, but it didn't work:
HSSFCellStyle cs = wb.createCellStyle();
HSSFDataFormat df = wb.createDataFormat();
cs.setDataFormat(df.getFormat("[h]:mm:ss"));
cellHorasPrevistas.setCellStyle(cs);
cellHorasPrevistas.setCellValue("01:00:00")
I have also tried with no lucky
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
fe.clearAllCachedResultValues()
fe.notifyUpdateCell(cellHorasPrevistas)
fe.evaluate(cellHorasPrevistas)
I must be quite easy, just to change a cell value a get that cell the same if I changed it manually in the xls.
Thanks in advance,
Raúl
Found a partial explanation....The problem is that de CellType is changing from number to String and consequently excel cannot use it in formulas. I want to mantain the number format setting the value as "12:00:00" and not to 0.5. Is it possible?
You could try using a Date or Calendar-Object to set the value and not a String. You may have to create a Dummy-Object, that only has the appropriate time set .
I had to set the YEAR to 1970, Month to January and Day to 1, to make it work like this:
HSSFWorkbook wb = new HSSFWorkbook();
HSSFRow row = wb.createSheet().createRow(0);
CellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(wb.getCreationHelper().createDataFormat().getFormat("HH:mm:ss"));
HSSFCell cell = row.createCell(1);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 1970);
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DATE, 1);
//you can set the time you need here ...
cell.setCellValue(cal);
cell.setCellStyle(cellStyle);
Result:
If I left the YEAR/MONTH/DATE part normal, the hours would be all the Hours since January, 1st 1970.
Firstly to update your formulas so you don't have to go into the file to keep hiting enter:
for .xlsx files
XSSFWorkbook workbook= new XSSFWorkbook(FilePath);
XSSFFormulaEvaluator.evaluateAllFormulaCells(workbook);
for .xls files
HSSFWorkbook workbook= new HSSFWorkbook(FilePath);
HSSFFormulaEvaluator.evaluateAllFormulaCells(workbook);
For putting time into excel I created a simple class file, so you can very easily just change all the inputs for the rows and columns. This is however for XSSF, but that shouldn't be an issue to change to HSSF.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class test {
public static void main(String [] args) {
System.out.println(Time());
}
public static String Time () {
Calendar cal = Calendar.getInstance();
SimpleDateFormat s = new SimpleDateFormat("HH:mm:ss"); //Changeable
return s.format(cal.getTime()).toString();
}
public void addtoExcel() throws IOException {
InputStream ExcelFileToRead = new FileInputStream(file_path);
XSSFWorkbook wb = new XSSFWorkbook(ExcelFileToRead);
XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
XSSFSheet sheet = wb.getSheetAt(0);
sheet.createRow(rowIndex).createCell(columnIndex).setCellValue(Time());
FileOutputStream out = new FileOutputStream(new File(file_path));
wb.write(out);
out.close();
}
}

Categories

Resources