How to separate data in multiple sheets in excel using java poi? - java

I have a java code that retrieves the data from the database and copies them to an excel sheet then creates a file,
but all the retrieval data are shown in 1 sheet my problem is to separate them into separated sheets regarding the date, please find my code and advise
List<Excelvo> excelvos = null;
String strDate = "28-02-2021";
String strToDate = "28-03-2021";
Workbook workbook = new XSSFWorkbook();
try {
excelvos = ExcelDao.getInstance().getShabanCodes(100, strDate, strToDate);
} catch (Exception ex) {
Logger.getLogger(CopyToExcel.class.getName()).log(Level.SEVERE, null, ex);
}
// Workbook workbook = new XSSFWorkbook(); // new HSSFWorkbook() for generating `.xls` file
//System.out.println(strDate.substring(0, 5));
/* CreationHelper helps us create instances of various things like DataFormat,
Hyperlink, RichTextString etc, in a format (HSSF, XSSF) independent way */
CreationHelper createHelper = workbook.getCreationHelper();
// Create a Sheet
// for loop to create more than 1 sheet
Sheet sheet = workbook.createSheet(strDate.substring(0, 5));
// Create a Font for styling header cells
Font headerFont = workbook.createFont();
headerFont.setFontHeightInPoints(
(short) 12);
headerFont.setColor(IndexedColors.BLACK.getIndex());
// Create a CellStyle with the font
CellStyle headerCellStyle = workbook.createCellStyle();
headerCellStyle.setFont(headerFont);
headerFont.setBoldweight(headerFont.BOLDWEIGHT_BOLD);
headerCellStyle.setFillBackgroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
headerCellStyle.setAlignment(headerCellStyle.ALIGN_CENTER);
// Create a Row
Row headerRow = sheet.createRow(0);
// Create cells
//for the table header.
for (int i = 0;
i < columns.length;
i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(columns[i]);
cell.setCellStyle(headerCellStyle);
}
// Create Cell Style for formatting Date
CellStyle dateCellStyle = workbook.createCellStyle();
dateCellStyle.setDataFormat(createHelper.createDataFormat().getFormat("dd-MM-yyyy HH:mm:ss"));
dateCellStyle.setBorderBottom(HSSFCellStyle.BORDER_MEDIUM);
dateCellStyle.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM);
dateCellStyle.setBorderRight(HSSFCellStyle.BORDER_MEDIUM);
dateCellStyle.setBorderTop(HSSFCellStyle.BORDER_MEDIUM);
headerCellStyle.setAlignment(headerCellStyle.ALIGN_CENTER);
dateCellStyle.setBorderBottom(CellStyle.BORDER_THIN);
dateCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
dateCellStyle.setBorderLeft(CellStyle.BORDER_THIN);
dateCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
dateCellStyle.setBorderRight(CellStyle.BORDER_THIN);
dateCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
dateCellStyle.setBorderTop(CellStyle.BORDER_THIN);
dateCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
// Create Other rows and cells with employees data
int rowNum = 1;
for (Excelvo excelvo
: excelvos) {
Row row = sheet.createRow(rowNum++);
row.createCell(0)
.setCellValue(excelvo.getCode());
row.createCell(1)
.setCellValue(excelvo.getSentDate());
row.createCell(2)
.setCellValue(excelvo.getCampaign());
row.createCell(3)
.setCellValue(excelvo.getMsisdn());
}
// Resize all columns to fit the content size
for (int i = 0;
i < columns.length;
i++) {
sheet.autoSizeColumn(i);
}
//String excelFilePath = "D:/Excel/MyFirstExcel.xlsx";
//FileInputStream inputStream = new FileInputStream(new File(excelFilePath));
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("sugar sha3ban campaign 2021 code log 28 Feb - 30 Mar.xlsx");
workbook.write(fileOut);
fileOut.close();
I need to separate the data into multiple sheets regarding the date
the retrieved data: each month has data I want to separate this data to put each month with their data in a sheet?

By using MemPOI you can simply execute different queries and bind them to different sheets, letting the db to apply the required filters. MemPOI will take care of the generation. Something like this:
MempoiSheet januarySheet = MempoiSheetBuilder.aMempoiSheet()
.withSheetName("January")
.withPrepStmt(conn.prepareStatement("SELECT * FROM MyTable WHERE date = 'mydate'"))
.build();
MempoiSheet februarySheet = MempoiSheetBuilder.aMempoiSheet()
.withSheetName("February")
.withPrepStmt(conn.prepareStatement("SELECT * FROM MyTable WHERE date = 'mydate 2'"))
.build();
MemPOI memPOI = MempoiBuilder.aMemPOI()
.withAdjustColumnWidth(true)
.addMempoiSheet(januarySheet)
.addMempoiSheet(februarySheet)
.build();

Related

Apache POI createTable generates corrupted file when a header's cell contains a line break

I am using Apache POI 4.1.2 to create Excel files in Java. I have a piece of code that creates a table from existing cells and everything used to work fine, untill I had a linebreak inside a header's cell.
I tried to change the table's column name afterward but it didn't fix anything.
Below is a minimal piece of code to reproduce the problem:
public void test() throws IOException {
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet();
// headers
XSSFRow headersRow = sheet.createRow(0);
headersRow.createCell(0).setCellValue("Column1");
headersRow.createCell(1).setCellValue("Column2");
// a second row
XSSFRow row = sheet.createRow(1);
row.createCell(0).setCellValue(1);
row.createCell(1).setCellValue(2);
// create a table
AreaReference area = wb.getCreationHelper().createAreaReference(
new CellReference(sheet.getRow(0).getCell(0)),
new CellReference(sheet.getRow(1).getCell(1))
);
XSSFTable table = sheet.createTable(area);
// styling (no problem here)
sheet.setColumnWidth(0, 5000);
sheet.setColumnWidth(1, 5000);
CTTable cttable = table.getCTTable();
cttable.addNewTableStyleInfo();
XSSFTableStyleInfo style = (XSSFTableStyleInfo) table.getStyle();
style.setName("TableStyleMedium6");
style.setShowColumnStripes(false);
style.setShowRowStripes(true);
cttable.addNewAutoFilter().setRef(area.formatAsString());
CellStyle cellStyle = wb.createCellStyle();
cellStyle.setWrapText(true);
headersRow.getCell(0).setCellStyle(cellStyle);
// this file is OK
try (FileOutputStream outputStream = new FileOutputStream("C:\\tmp\\test.xlsx")) {
wb.write(outputStream);
}
// add a line break in a header's cell
headersRow.getCell(0).setCellValue("Column1\nwith a line break");
// this file has a problem
try (FileOutputStream outputStream = new FileOutputStream("C:\\tmp\\test2.xlsx")) {
wb.write(outputStream);
}
// this doesn't fix anything
table.getColumns().get(0).setName("Column1");
try (FileOutputStream outputStream = new FileOutputStream("C:\\tmp\\test3.xlsx")) {
wb.write(outputStream);
}
// neither does this
cttable.getTableColumns().getTableColumnList().get(0).setName("Column1");
try (FileOutputStream outputStream = new FileOutputStream("C:\\tmp\\test4.xlsx")) {
wb.write(outputStream);
}
}
Excel loads text.xlsx properly, but complains about all other files:
We found a problem with some content...
After Excel fixes the files, everything is OK but I would like to get rid of the warning message.
Any help will be appreciated.
Thanks
This is an inaccuracy with XSSFTable.updateHeaders. This method gets called while the table's XML gets written. This is because the table column names always must be synchronized with the cell contents. For example if the cell content is "Column1" and this cell is a column header of a table, then this tables column name also must be "Column1" (XML: <tableColumn id="1" name="Column1"/>).
But for line feeds in column headers, there is a specialty. If the cell content is "Column1\nwith a line break" and this cell is a column header of a table, then this tables column name must be XML as <tableColumn id="1" name="Column1_x000a_with a line break"/>. So "\n" is replaced by "x000a". Also "\r" would must be replaced by "x000d". This is because "\r\n" line breaks will not have the meaning of line break in XML.
So XSSFTable.java - updateHeaders would must be patched that way that "\n" gets replaced by "x000a" and "\r" gets replaced by "x000d".
...
public void updateHeaders() {
XSSFSheet sheet = (XSSFSheet)getParent();
CellReference ref = getStartCellReference();
if (ref == null) return;
int headerRow = ref.getRow();
int firstHeaderColumn = ref.getCol();
XSSFRow row = sheet.getRow(headerRow);
DataFormatter formatter = new DataFormatter();
if (row != null && row.getCTRow().validate()) {
int cellnum = firstHeaderColumn;
CTTableColumns ctTableColumns = getCTTable().getTableColumns();
if(ctTableColumns != null) {
for (CTTableColumn col : ctTableColumns.getTableColumnList()) {
XSSFCell cell = row.getCell(cellnum);
if (cell != null) {
String colName = formatter.formatCellValue(cell);
colName = colName.replace("\n", "_x000a_");
colName = colName.replace("\r", "_x000d_");
col.setName(colName);
}
cellnum++;
}
}
}
tableColumns = null;
columnMap = null;
xmlColumnPrs = null;
commonXPath = null;
}
...
Since XSSFTable.updateHeaders gets called while the table's XML gets written while XSSFWorkbook.write, there is no other way than patching this method. One does not have any chance to change table's XML while XSSFWorkbook.write.

POI CellStyle does not appear to be applied

Please note: I see a very similar question asked here but that answer was not very conclusive (I can't discern what the actual fix is/was). If someone can explain to me how that question/answer addresses my present issue at hand, I will happily delete this question myself! Just please don't DV/CV as a "dupe", and instead please help me make sense of that provided solution!
Java 8 and POI 4.1.x here. I am trying to write some Java/POI code that will produce a styled/formatted Excel file as output. I have created this GitHub project that perfectly reproduces the issue I'm seeing. If you really want, you can take a look at it and run it (its a Swing app) via ./gradlew clean build shadowJar && java -jar build/libs/hello-windows.jar, but the TLDR; of it is:
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("SOME_SHEET");
Font headerFont = workbook.createFont();
headerFont.setBold(true);
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setFont(headerFont);
cellStyle.setFillBackgroundColor(IndexedColors.YELLOW.getIndex());
cellStyle.setAlignment(HorizontalAlignment.CENTER);
int rowNum = 0;
Row headerRow = sheet.createRow(rowNum);
headerRow.setRowStyle(cellStyle);
Cell partNumberHeaderCell = headerRow.createCell(0);
partNumberHeaderCell.setCellValue("Part #");
partNumberHeaderCell.setCellStyle(cellStyle);
Cell partDescriptionHeaderCell = headerRow.createCell(1);
partDescriptionHeaderCell.setCellStyle(cellStyle);
partDescriptionHeaderCell.setCellValue("Description");
Cell partPriceHeaderCell = headerRow.createCell(2);
partPriceHeaderCell.setCellStyle(cellStyle);
partPriceHeaderCell.setCellValue("Price");
Cell manufacturerHeaderCell = headerRow.createCell(3);
manufacturerHeaderCell.setCellStyle(cellStyle);
manufacturerHeaderCell.setCellValue("Make");
rowNum++;
Row nextRow = sheet.createRow(rowNum);
nextRow.createCell(0).setCellValue(uuid);
nextRow.createCell(1).setCellValue("Some Part");
nextRow.createCell(2).setCellValue(2.99);
nextRow.createCell(3).setCellValue("ACME");
FileOutputStream fos = null;
try {
fos = new FileOutputStream("acme.xlsx");
workbook.write(fos);
workbook.close();
} catch (IOException ex) {
log.error(ExceptionUtils.getStackTrace(ex));
}
When this code runs it produces an Excel file that contains all my data (the header row and a "data" row) correctly, however all the formatting and cell styling seems to be ignored:
In the screenshot above, you can see that the header is not styled at all, however I believe I am styling it correctly:
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setFont(headerFont);
cellStyle.setFillBackgroundColor(IndexedColors.YELLOW.getIndex());
cellStyle.setAlignment(HorizontalAlignment.CENTER);
If my code is correct then I should see a header that:
Has a yellow background; and
Is horizontally-centered/aligned; and
Is bolded
Can anyone spot where I'm going awry?
Not clear why the bold font not gets applied for you, for me it gets.
But the problem with the cell interior is that Excel cell interiors have pattern fills. There the fill background color is the color behind the pattern and the fill foreground color is the color of the pattern. Solid filled cell interiors must have solid pattern having the needed fill foreground color set.
See also Busy Developers' Guide to HSSF and XSSF Features.
...
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setFont(headerFont);
//cellStyle.setFillBackgroundColor(IndexedColors.YELLOW.getIndex());
cellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
...
Let's have a complete example which will store your data in an Excel sheet:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
class CreateExcelCellStyle {
public static void main(String[] args) throws Exception {
try (Workbook workbook = new XSSFWorkbook();
FileOutputStream fileout = new FileOutputStream("./Excel.xlsx") ) {
Font headerFont = workbook.createFont();
headerFont.setBold(true);
CellStyle headerStyle = workbook.createCellStyle();
headerStyle.setFont(headerFont);
headerStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
headerStyle.setAlignment(HorizontalAlignment.CENTER);
Object[][] data = new Object[][] {
new Object[] {"Part #", "Description", "Price", "Make"},
new Object[] {"cb82c02", "Some Part", 2.99, "ACME"}
};
Sheet sheet = workbook.createSheet();
for (int r = 0; r < data.length; r++) {
Row row = sheet.createRow(r);
for (int c = 0; c < data[0].length; c++) {
Cell cell = row.createCell(c);
if (r==0) cell.setCellStyle(headerStyle);
Object content = data[r][c];
if (content instanceof String) {
cell.setCellValue((String)content);
} else if (content instanceof Double) {
cell.setCellValue((Double)content);
}
}
}
for (int c = 0; c < data[0].length; c++) {
sheet.autoSizeColumn(c);
}
workbook.write(fileout);
}
}
}
Result:

How to write the List data in Excel

List having data in this format
[{Row ID=7565.0, Product ID=test11223, Postal Code=98103.0}, {Row ID=7567.0, Product ID=test11213, Postal Code=98101.0}] Having more than 100 row ID record like this, I want to store that data in Excel in below format
Row Id Order ID Postal Code
7565 test11233 98103
7567 test11233 98101
Please help to share the code to write a above list data in excel. thnx
With Apache POI you can write any kind of MS Office files.
Here is a quick example how write cells with it.
Workbook wb = new HSSFWorkbook();
//Workbook wb = new XSSFWorkbook();
CreationHelper createHelper = wb.getCreationHelper();
Sheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
Row row = sheet.createRow(0);
// Create a cell and put a value in it.
Cell cell = row.createCell(0);
cell.setCellValue(1);
// Or do it on one line.
row.createCell(1).setCellValue(1.2);
row.createCell(2).setCellValue(
createHelper.createRichTextString("This is a string"));
row.createCell(3).setCellValue(true);
// Write the output to a file
try (OutputStream fileOut = new FileOutputStream("workbook.xls")) {
wb.write(fileOut);
}

Exporting xlsx using apache poi 3.13 on weblogic : File format or extension not valid

Earlier I was using Apache POI 2.5.1 to export .xls file using HSSFWorkbook.
With updated Apache POI to 3.13 I am exporting .xlsx file using SXSSFWorkbook but its exporting corrupted file.
MS Excel failed to open file with File format or extension not valid error.
Note that this issue I am facing only on WebLogic server, it works fine with JBoss.
Anybody can help what I am doing wrong here ?
Code:
List<JRField> fields = ds.getFields();
SXSSFWorkbook wb = new SXSSFWorkbook();
SXSSFSheet sheet = wb.createSheet("Sheet1");
try {
CellStyle cellStyle = wb.createCellStyle();
CellStyle cellStyleColName = wb.createCellStyle();
CellStyle cellStyleTitle = wb.createCellStyle();
Font boldFont = wb.createFont();
boldFont.setFontHeightInPoints((short)16);
boldFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
// Cell Style for body
cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)"));
cellStyle.setWrapText(true);
// Cell Style for Column Names
cellStyleColName.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)"));
cellStyleColName.setAlignment(HSSFCellStyle.ALIGN_CENTER);
cellStyleColName.setBorderTop(HSSFCellStyle.BORDER_MEDIUM); // single line border
cellStyleColName.setBorderBottom(HSSFCellStyle.BORDER_MEDIUM); // single line border
// Cell Style for Title
cellStyleTitle.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)"));
cellStyleTitle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
cellStyleTitle.setFont(boldFont);
// Creating Title Row
Row row1 = sheet.createRow((short) 0);
// Creating the Title line
Cell cell1 = row1.createCell((short) 0);
cell1.setCellValue("Demo Title");
cell1.setCellStyle(cellStyleTitle);
// Title Region
CellRangeAddress regionTitle = new CellRangeAddress( (short) 0, // From Row
(short) 0, // From Col
(short) 0, // To Row
(short) (this.displayCols.size()-1) // To Col
);
sheet.addMergedRegion(regionTitle);
// Column Name Row
int j =0;
Row row2 = sheet.createRow((short) 1);
for (ReportColumn col : this.displayCols)
{
Cell cell2 = row2.createCell((short) j++);
cell2.setCellValue(col.getDisplayName());
cell2.setCellStyle(cellStyleColName);
}
int i =2;
while (ds.next()) {
Row rows = sheet.createRow((short) 0 + i);
int k = 0;
for (JRField field : fields) {
String fieldAsString = (ds.getFieldValue(field) != null ? ds.getFieldValue(field).toString():null);
Cell cell = rows.createCell((short) k++);
cell.setCellStyle(cellStyle);
cell.setCellValue(fieldAsString);
}
i++;
if (i > RECORD_LIMIT_FROM_POI){
log.info("Row limit from poi reached #1048576 and exported data is truncated.");
break;
}
}
wb.write(os);
}
catch (Exception e) {
log.error("error in createXlsFile method", e);
}
Failed attempts:
Updated mime type in response header from application/vnd.ms-excel
to vnd.openxmlformats-officedocument.spreadsheetml.sheet
Added xlsx=vnd.openxmlformats-officedocument.spreadsheetml.sheet in custom mime mapping file for WebLogic
This may be more resource heavy, but have you tried:
XSSFWorkbook wb = new SXSSFWorkbook();
XSSFSheet sheet = wb.createSheet("Sheet1");
instead of SXSSF.
There is some discussion between the various types here: HSSFWorkbook vs XSSFWorkbook and the advantages/disadvantages of XSSFWorkbook and SXSSFWorkbook?

Generate Excel Report in Android with Sqlite Database

I have new hand on Android. I have made a report using ListView which is divided into three columns named DateTime, OnOffStatus, AlarmImage.
It work fine and looks good enough but now I want to export this table data to Excel format. Is it possible or not and how?
thanks in advance
Om Parkash Kaushik
Start of by looking at http://poi.apache.org/ and http://poi.apache.org/spreadsheet/index.html
I use this library to all of my excel reports.
Start of by creating a Workbook:
HSSFWorkbook workbook = new HSSFWorkbook();
Map<String, CellStyle> styles = createStyles(workbook);
HSSFSheet sheet = workbook.createSheet();
Setup some style:
private static Map<String, CellStyle> createStyles(Workbook wb) {
Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
CellStyle style;
Font monthFont = wb.createFont();
monthFont.setFontHeightInPoints((short) 11);
monthFont.setColor(IndexedColors.WHITE.getIndex());
style = wb.createCellStyle();
style.setAlignment(CellStyle.ALIGN_CENTER);
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setFillPattern(CellStyle.SOLID_FOREGROUND);
style.setFont(monthFont);
style.setWrapText(true);
styles.put("header", style);
style = wb.createCellStyle();
style.setAlignment(CellStyle.ALIGN_CENTER);
style.setWrapText(true);
style.setBorderRight(CellStyle.BORDER_NONE);
style.setBorderLeft(CellStyle.BORDER_NONE);
style.setBorderTop(CellStyle.BORDER_NONE);
style.setBorderBottom(CellStyle.BORDER_NONE);
styles.put("cell", style);
return styles;
}
Then setup a header row:
private static final String[] article_headers = {"header1", "header2"};
// Header row
Row headerRow = sheet.createRow(0);
headerRow.setHeightInPoints(40);
Cell headerCell;
for (int i = 0; i < article_headers.length; i++) {
headerCell = headerRow.createCell(i);
headerCell.setCellValue(article_headers[i]);
headerCell.setCellStyle(styles.get("header"));
}
And then you continue with the rows by setting their style and value.
Hope this helps and if you find this helpful, remember to accept.
// Jakob

Categories

Resources