I have a Word table with 1 row and 2 columns, and I want to insert a new row with 3 columns using Apache poi with Java. What I want to achieve is this:
But what I get is this:
I have searched the Internet for a solution but all I get was about setting column width which does not work for my case. Could anyone help me with this problem?
This is my code which I took from one of the examples in Stack Overflow to work around that yield the output shown in second picture:
File file = new File("C:\\Users\\USER\\Desktop\\testdoc.docx");
XWPFDocument doc = new XWPFDocument(new FileInputStream(file));
FileOutputStream out = new FileOutputStream(file);
XWPFTable table = doc.getTableArray(0);
XWPFTableRow oldRow = table.getRow(0);
table.insertNewTableRow(1);
XWPFTableRow newRow = table.getRow(1);
int indWidth = 0;
for(int i=0; i < oldRow.getTableCells().size(); i++) {
int sum = 0;
BigInteger width = oldRow.getCell(i).getCTTc().getTcPr().getTcW().getW();
sum += width.intValue();
indWidth = sum/oldRow.getTableCells().size();
}
XWPFTableCell cell;
for (int i = 0; i < 3; i++) {
cell = newRow.createCell();
CTTcPr ctTcPr = cell.getCTTc().addNewTcPr();
CTTblWidth cellWidth = ctTcPr.addNewTcW();
cellWidth.setType(oldRow.getCell(0).getCTTc().getTcPr().getTcW().getType()); // sets type of width
BigInteger width = BigInteger.valueOf(indWidth);
cellWidth.setW(width); // sets width
if (oldRow.getCell(0).getCTTc().getTcPr().getGridSpan() != null) {
ctTcPr.setGridSpan(oldRow.getCell(0).getCTTc().getTcPr().getGridSpan()); // sets grid span if any
}
XWPFRun run = cell.getParagraphs().get(0).createRun();
run.setText("NewRow C" + i);
}
doc.write(out);
doc.close();
System.out.println("Done");
}
I can propose a solution, for the java world, but not with poi...
With pxDoc (www.pxdoc.fr, disclaimer: I am one of its authors...), this can be perfectly achieved with the following code :
document {
table {
row {
cell { "Column 1" }
cell { "Column 2" }
}
row {
for (var i = 0; i < 3; i++) {
cell {
"NewRow C" + i
}
}
}
}
}
Related
I am trying to make use of Apache POI to read an excel file and convert it to a 2-dimensional object array. Attached is the code section.
Workbook workbook = new XSSFWorkbook(inputStream);
Sheet firstSheet = workbook.getSheetAt(1);
int numRows = 3;
int cols = 5;
double[][] excelData = new double[numRows][cols];
for (int i = 1; i < numRows; i++) {
Row row = firstSheet.getRow(i);
if (row != null) {
for (int j = 1; j < cols; j++) {
Cell cell = row.getCell(j);
if (cell != null) {
try {
excelData[i][j] = cell.getNumericCellValue();
} catch (IllegalStateException e) {
System.out.println("Cell data is not a double");
}
}
}
}
}
workbook.close();
inputStream.close();
return excelData;
}
enter image description here This is my excel sheet and I want to "just" read the blue part of it as a 2d array, but after running the code the first row and column all are zero and I don't want it, appreciate your help on how can quickly pull out all the zeros enter image description here.
You need to change index in the 1st loop to 0 (first field in excel file)
but in row you must provide index + 1 bc you need to read from the 2nd field.
Same analogy for 2nd loop and cell field
Workbook workbook = new XSSFWorkbook(new File("d:\\book1.xlsx"));
Sheet firstSheet = workbook.getSheetAt(1);
int numRows = 3;
int cols = 5;
double[][] excelData = new double[numRows][cols];
for (int i = 0; i < numRows; i++) {
Row row = firstSheet.getRow(i + 1);
if (row != null) {
for (int j = 0; j < cols; j++) {
Cell cell = row.getCell(j + 1);
if (cell != null) {
try {
if (cell.getCellType().equals(CellType.NUMERIC)) {
excelData[i][j] = Double.valueOf(cell.getNumericCellValue());
}
} catch (IllegalStateException e) {
System.out.println("Cell data is not a double");
}
}
}
}
}
workbook.close();
Returned result for it:
0.041256 0.033079 -0.01138 -0.02138 -0.01138
0.041256 0.033079 -0.01138 -0.01138 -0.01138
0.020628 0.01654 -0.00569 -0.10569 -0.00569
I am building a function that reads the data available in the excel file.
I use Apache POI with the Spring project.
However, I am having trouble reading with merge cells. What I need is to get the content highlighted in red as shown in the picture.
Can you suggest me the code?
Thanks !
Update:
`
public void importClassroomByExcel(MultipartFile file) {
try {
Workbook workbook = new HSSFWorkbook(file.getInputStream());
Iterator<Sheet> sheetIterator = workbook.iterator();
while (sheetIterator.hasNext()) {
Sheet sheet = sheetIterator.next();
String title = sheet.getRow(4).getCell(5).toString();
}
workbook.close();
} catch (Exception e) {
throw new BadRequestAlertException(ErrorConstants.DEFAULT_TYPE, "", e.getMessage(), "filestructerror",
Status.BAD_REQUEST);
}
}
`
Not sure I understand your requirement correct. This is what I think you want: In your sheet, the data range starts in row 5 and column A determines the grouping. Now the need is getting the values of columns F and G for each group. Then the need is getting the first date for each group in column N and the last date for each group in column O.
So the need is to get the first row for each group and the last filled row for each group. Following example shows this. Mainly it uses a method int getNextFilledRow(Sheet sheet, int columnNum, int startRowNum) to get the next filled row in a given column of the sheet starting on a given row number.
The code should only get the cells having the red marked contents in your given sheet.
import java.io.FileInputStream;
import org.apache.poi.ss.usermodel.*;
class ReadExcelMergedCells {
static int getNextFilledRow(Sheet sheet, int columnNum, int startRowNum) {
int lastRow = sheet.getLastRowNum();
int nextFilledRow = lastRow;
for (int r = startRowNum; r <= lastRow; r++) {
nextFilledRow = r + 1;
Row row = sheet.getRow(nextFilledRow);
Cell cell = (row != null)?cell = row.getCell(columnNum):null;
if (cell != null && cell.getCellType() != CellType.BLANK) {
break;
}
}
return nextFilledRow;
}
public static void main(String[] args) throws Exception {
Workbook workbook = WorkbookFactory.create(new FileInputStream("./Excel.xlsx"));
Sheet sheet = workbook.getSheetAt(0);
int lastRow = sheet.getLastRowNum();
int startRow = 4;
Row row = null;
Cell cell = null;
int columnNum = -1;
int columNumA = 0; //column A determines the grouping
for (int r = startRow; r <= lastRow; r = getNextFilledRow(sheet, columNumA, r)) {
//r is the first row in this group
System.out.println("Group starting in row " + r);
//get cell in column F of first row in this group
columnNum = 5;
row = sheet.getRow(r);
cell = (row != null)?cell = row.getCell(columnNum):null;
System.out.println(cell);
//get cell in column G of first row in this group
columnNum = 6;
row = sheet.getRow(r);
cell = (row != null)?cell = row.getCell(columnNum):null;
System.out.println(cell);
//get cell in column N of first row in this group
columnNum = 13;
row = sheet.getRow(r);
cell = (row != null)?cell = row.getCell(columnNum):null;
System.out.println(cell);
//get cell in column O of last filled row in this group
columnNum = 14;
int lastRowInGroup = getNextFilledRow(sheet, columNumA, r) -1;
// get last filled cell in this group
for (int rl = lastRowInGroup; rl >= r; rl--) {
row = sheet.getRow(rl);
cell = (row != null)?cell = row.getCell(columnNum):null;
if (cell != null && cell.getCellType() != CellType.BLANK) {
break;
}
}
System.out.println(cell);
System.out.println("Group ending in row " + lastRowInGroup);
}
workbook.close();
}
}
Code to change color of cell to red:
CellStyle cellStyle = cell.getCellStyle();
Font font = workbook.createFont();
font.setFontName("Times New Roman");
font.setColor(IndexedColors.RED.index);
cellStyle.setFont(font);
cellStyle.setFillBackgroundColor(IndexedColors.BLUE.index);
cell.setCellStyle(cellStyle);
To merge from B2 to E2:
sheet.addMergedRegion(new CellRangeAddress(1,1,1,4));
See more in :
Changing cell color using apache poi
How to get the font style of a cell field of excel in Java, Apache POI?
Using custom colors with SXSSF (Apache POI)
Merging cells in Excel using Apache POI
We are displaying a number and a percent like "2 (100%)" in each cell.
I would like to apply different formatting to the Number part and percentage part. It seems not possible to apply different formatting, within a cell.
So I'm trying to write data into 2 consecutive cells, which have different formatting and then merge it.
But after merging , the data in the second cell is lost.
How can I merge, with both cells data merged to single cell ?
HSSFFont percentFont = wb.createFont();
percentFont.setFontName(HSSFFont.FONT_ARIAL);
percentFont.setFontHeightInPoints((short) 10);
percentFont.setBold(true);
percentStyle.setFont(percentFont);
for (int i = 0; i < rows.size(); i++) {
List<String> rowData = rows.get(i);
int rowNumber = 9 + i;
HSSFRow row1 = sheet.createRow(rowNumber);
int colNumber = 0;
for (int j = 0; j < count; j++) {
HSSFCell hssfMainCell = row1.createCell(colNumber);
HSSFCell hssfPercentCell = row1.createCell(colNumber + 1);
hssfPercentCell.setCellStyle(percentStyle);
String val = rowData.get(j);
String percentage = "(" + rowData.get(percentageColumns.get(j)) + "%)";
;
hssfMainCell.setCellValue(val);
hssfMainCell.setCellStyle(rightAligned);
if (percentageColumns.get(j) != null) {
hssfPercentCell.setCellValue(percentage);
percentStyle.setAlignment(CellStyle.ALIGN_RIGHT);
hssfPercentCell.setCellStyle(percentStyle);
sheet.addMergedRegion(new CellRangeAddress(rowNumber, rowNumber, colNumber, colNumber + 1));
colNumber++;
colNumber++;
}
}
}
I am having an excel with 2 rows and 5 columns. Now I entered code manually to take values from 1st row. How can I iterate the process?
Below is the code for 1st row in excel. From the 2nd row on, I dont know how to do... I want to iterate one row after another.
Workbook workbook = Workbook.getWorkbook(new File(
"\\C:\\users\\a-4935\\Desktop\\DataPool_CA.xls"));
Sheet sheet = workbook.getSheet("Sheet1");
System.out.println("Reached to Sheet");
Cell a = sheet.getCell(2,1);
Cell b = sheet.getCell(3,1);
Cell c = sheet.getCell(4,1);
Cell d = sheet.getCell(5,1);
Cell e = sheet.getCell(6,1);
Cell f = sheet.getCell(7,1);
Cell g = sheet.getCell(8,1);
Cell h = sheet.getCell(9,1);
Cell i = sheet.getCell(10,1);
String uId = a.getContents();
String deptFromDat = b.getContents();
String deptToDate = c.getContents();
String dept1 = d.getContents();
String arrival1 = e.getContents();
String eihon1 = f.getContents();
String branchCode1 = g.getContents();
String userType1 = h.getContents();
String sessionId1 = i.getContents();
Use the code below to iterate over all rows of a datasheet:
Sheet sheet = workbook.getSheet("Sheet1");
for (Row row : sheet) {
for (Cell cell : row) {
//your logic
}
}
Or, alternatively, use the following code:
Sheet sheet = workbook.getSheet("Sheet1");
for (int i = 0; i < 2; i++) {
Row row = sheet.getRow(i);
if(row == null) {
//do something with an empty row
continue;
}
for (int j = 0; j < 5; j++) {
Cell cell = row.getCell(j);
if(cell == null) {
//do something with an empty cell
continue;
}
//your logic
}
}
for (int i = 0; i <= sheet.getLastRowNum (); ++i) {
row=(Row) sheet.getRow(i);
Iterator<Cell> cells = row.cellIterator();
while (cells.hasNext())
{ .....
you can use the above code to iterate all rows and all cells
You just need to change 1 to the row number, and use a for loop.
Based on your code you could do the following e.g.
For exmaple:
for(int i=0; i<number; i++)
{
Cell a = sheet.getCell(2,i);
Cell b = sheet.getCell(3,i);
Cell c = sheet.getCell(4,i);
...
}
Or better yet move the Cell declarations out of the for loop which is better practice.
Cell a,b, c...;
for(int i=0; i<number; i++)
{
a = sheet.getCell(2,i);
b = sheet.getCell(3,i);
c = sheet.getCell(4,i);
...
}
I am new to Apache-poi and using 3.8 version of poi. While writing value in the Excel,i check for the column names if they matched, i will write some value in that column and finish it, and again i will start writing on header. The problem is if write three column values only last column values are add or saved and first two values are not saved in the column. Can anyone tell what went wrong.
(sorry, in case any mistake)
Code:
int i = 0;
Row row = sheet.createRow(i);
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setFillBackgroundColor(HSSFColor.LIGHT_ORANGE.index);
String validate_header = null;
while (iterator.hasNext()) {
if (eiterator.hasNext()) {
validate_header = eiterator.next();
}
Cell cell = row.createCell(i);
String col_heading = iterator.next();
cell.setCellValue(col_heading);
if(col_heading.equalsIgnoreCase("Assigned Date"))
{
Add_value(i, col_heading, row, sheet);
row=sheet.getRow(0);
cell=row.getCell(i);
}
else if(col_heading.startsWith("Review"))
{
int count=-1;
int n=Col_values.get("Defect Summary").size();
for (int j = 0; j < n; j++) {
row = sheet.createRow(count);
cell = row.createCell(i);
String s="External QC Defect ";
cell.setCellValue(s);
count++;
}
row=sheet.getRow(0);
cell=row.getCell(i);
}
sheet.autoSizeColumn(i);
i++;
}
private static Sheet Add_value(int k,String name,Row row, Sheet sheet) {
System.out.println("Inside the add method");
if(name.equalsIgnoreCase("Assigned Date")||name.equalsIgnoreCase("Reported Date") )
{
vector = Col_values.get("TargetDate");
int count = 1;
System.out.println("IF Size of the vector " + vector.size());
for (int j = 0; j < vector.size(); j++) {
row = sheet.createRow(count);
cell = row.createCell(k);
String s = (String) vector.get(j);
System.out.println(s);
cell.setCellValue(s);
count++;
}
}
else
{
vector = Col_values.get("Defect Summary");
int count = 1;
System.out.println("ELSE Size of the vector " + vector.size());
for (int j = 0; j < vector.size(); j++) {
row = sheet.createRow(count);
cell = row.createCell(k);
String s = (String) vector.get(j);
System.out.println(s);
cell.setCellValue(s);
count++;
}
}
return sheet;
}
'
Can u tell what went Wrong?
It seems that Add_value starts creating rows from top. Therefore on the second call the old rows are removed.
Replace
row = sheet.createRow(count);
with
row = k == 0 ? sheet.createRow(count) : sheet.getRow(count);