I'm writing a program in POI to merge cells and I'm able to merge them. there is a column with number content, and when I merge this column and when I open my sheet and select this column to my surprise this shows the count and sum as if it is not merged.
Below is my Excel.
Here the count should be 5 and sum should be 530 but this shows this as 25 and 2650
Below is my code.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
public class RowsMerge {
// public static void main(String[] args)
public static void main(String[] args) throws IOException {
FileInputStream fin = new FileInputStream(
new File("C:\\D\\Sheets\\Quality Sheet\\Quality_template.xls"));
HSSFWorkbook workbook = new HSSFWorkbook(fin);
HSSFSheet sheet = workbook.getSheetAt(0);
int row = sheet.getPhysicalNumberOfRows();
String currentLawName, currentCountry, currentAssociate, previousLawName, previousCountry, previousAssociate;
String currentPages, previousPages;
int startIndex = 1, finalIndex = 0;
System.out.println(row);
for (int i = 2; i < row; i++) {
currentAssociate = sheet.getRow(i).getCell(1).toString();
currentLawName = sheet.getRow(i).getCell(3).toString();
currentCountry = sheet.getRow(i).getCell(4).toString();
currentPages = sheet.getRow(i).getCell(5).toString();
previousAssociate = sheet.getRow(i - 1).getCell(1).toString();
previousLawName = sheet.getRow(i - 1).getCell(3).toString();
previousCountry = sheet.getRow(i - 1).getCell(4).toString();
previousPages = sheet.getRow(i - 1).getCell(5).toString();
if (currentAssociate.equals(previousAssociate) && currentCountry.equals(previousCountry)
&& currentLawName.equals(previousLawName) && currentPages.equals(previousPages)) {
finalIndex += 1;
if (((i + 1) == row)) {
System.out.println("yes");
finalIndex += 1;
sendRangeToMergeCells(startIndex + 1, finalIndex - 1, sheet, workbook);
}
} else {
sendRangeToMergeCells(startIndex + 1, finalIndex, sheet, workbook);
startIndex = i;
finalIndex = 0;
}
}
FileOutputStream fileOut = new FileOutputStream("C:\\D\\Sheets\\Quality Sheet\\new.xls");
workbook.write(fileOut);
fileOut.close();
}
private static void sendRangeToMergeCells(int startIndex, int finalIndex, HSSFSheet sheet, HSSFWorkbook workbook) {
System.out.println(startIndex + "\t" + (startIndex + finalIndex));
CellRangeAddress region = CellRangeAddress.valueOf("F" + (startIndex) + ":F" + ((startIndex + finalIndex)));
sheet.addMergedRegion(region);
}
}
How can I fix this?
This may be the result of a bug, but a workaround may be to shift the rows up instead of merging them.
public class RowsMerge {
// public static void main(String[] args)
public static void main(String[] args) throws IOException {
FileInputStream fin = new FileInputStream(
new File("C:\\D\\Sheets\\Quality Sheet\\Quality_template.xls"));
HSSFWorkbook workbook = new HSSFWorkbook(fin);
HSSFSheet sheet = workbook.getSheetAt(0);
int lastRow = sheet.getLastRowNum();
String currentLawName, currentCountry, currentAssociate, previousLawName, previousCountry, previousAssociate;
String currentPages, previousPages;
int rowCount = 0;
System.out.println(row);
for (int i = 2; i <= lastRow; i++) {
currentAssociate = sheet.getRow(i).getCell(1).toString();
currentLawName = sheet.getRow(i).getCell(3).toString();
currentCountry = sheet.getRow(i).getCell(4).toString();
currentPages = sheet.getRow(i).getCell(5).toString();
previousAssociate = sheet.getRow(i - 1).getCell(1).toString();
previousLawName = sheet.getRow(i - 1).getCell(3).toString();
previousCountry = sheet.getRow(i - 1).getCell(4).toString();
previousPages = sheet.getRow(i - 1).getCell(5).toString();
if (currentAssociate.equals(previousAssociate) && currentCountry.equals(previousCountry)
&& currentLawName.equals(previousLawName) && currentPages.equals(previousPages)) {
rowCount += 1;
}
} else {
shiftRowsUp(sheet, i, rowCount);
i -= rowCount;
rowCount = 0;
}
}
shiftRowsUp(sheet, i, rowCount);
FileOutputStream fileOut = new FileOutputStream("C:\\D\\Sheets\\Quality Sheet\\new.xls");
workbook.write(fileOut);
fileOut.close();
}
private void shiftRowsUp(Sheet sheet, int startRow, int rowCount) {
if (rowCount > 0) {
int lastRow = sheet.getLastRowNum();
if (lastRow - startRow < rowCount) {
for (int i = startRow - rowCount; i < startRow: i++) {
sheet.removeRow(sheet.getRow(i));
}
}
sheet.shiftRows(startRow, lastRow, -rowCount);
}
}
}
Note, this looping assumes that there are no gaps in the rows of the spreadsheet.
Related
I am using iText 7.1.15 in combination with Apache POI 4.1.1 to create a PDF from an Excel sheet.
The rows in the sheet are set to a specific height in centimeters to fit correctly on an A4 page when printed.
However when I set the cell height via iText and have a look at the result the row in the PDF table isn't exactly as high as in Excel.
I am using org.apache.poi.ss.usermodel.Row.getHeightInPoints() and set this value to my PDF table cell using com.itextpdf.layout.element.Cell.setHeight().
Inspecting the result however the row height in my PDF is slightly different than expected.
And some content (the last row in my sample) event gets truncated (I guess because the cell isn't high enough)...
What am I doing wrong here?
You can find the complete sample here at Github
PDF:
Excel:
for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
Row row = sheet.getRow(rowNum);
if (row == null) {
continue;
}
float heightInPoints = row.getHeightInPoints();
System.out.println("Row: " + (rowNum + 1) + ": " + heightInPoints + "pt = " + heightInPoints * PT_TO_CM + "cm");
for (int cellNum = 0; cellNum < numCols; cellNum++) {
Cell cell = row.getCell(cellNum, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
com.itextpdf.layout.element.Cell pdfCell = new com.itextpdf.layout.element.Cell();
pdfCell.add(new Paragraph(cell.getStringCellValue()));
pdfCell.setHeight(heightInPoints);
pdfCell.setBorder(new SolidBorder(0.5f));
table.addCell(pdfCell);
}
}
package com.gi.itext;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.SolidBorder;
import com.itextpdf.layout.element.AreaBreak;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.AreaBreakType;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class App {
private static final String OUTPUT = "./target/output.pdf";
private static final String INPUT = "/input.xlsx";
private static final float PT_TO_CM = 0.0352778f;
public static void main(String[] args) {
new App().run();
}
public void run() {
File file = new File(OUTPUT);
file.getParentFile().mkdirs();
try (InputStream is = getClass().getResourceAsStream(INPUT);
Workbook workbook = new XSSFWorkbook(is)) {
PdfDocument pdfDoc;
try {
pdfDoc = new PdfDocument(new PdfWriter(OUTPUT));
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
}
pdfDoc.addNewPage();
Document doc = new Document(pdfDoc, PageSize.A4);
for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
Sheet sheet = workbook.getSheetAt(sheetNum);
if (sheetNum > 0) {
doc.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
}
int numCols = getNumberOfColumns(sheet);
float[] columnWidth = new float[numCols];
for (int j = 0; j < numCols; j++) {
float columnWidthInPixels = sheet.getColumnWidthInPixels(j);
double columnWidthInPoints = columnWidthInPixels * 0.75d;
columnWidth[j] = (float) columnWidthInPoints;
}
Table table = new Table(columnWidth);
table.useAllAvailableWidth();
for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
Row row = sheet.getRow(rowNum);
if (row == null) {
continue;
}
float heightInPoints = row.getHeightInPoints();
System.out.println("Row: " + (rowNum + 1) + ": " + heightInPoints + "pt = " + heightInPoints * PT_TO_CM + "cm");
for (int cellNum = 0; cellNum < numCols; cellNum++) {
Cell cell = row.getCell(cellNum, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
com.itextpdf.layout.element.Cell pdfCell = new com.itextpdf.layout.element.Cell();
pdfCell.add(new Paragraph(cell.getStringCellValue()));
pdfCell.setHeight(heightInPoints);
pdfCell.setBorder(new SolidBorder(0.5f));
table.addCell(pdfCell);
}
}
doc.add(table);
}
doc.close();
pdfDoc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private int getNumberOfColumns(Sheet sheet) {
int firstRowNum = sheet.getFirstRowNum();
int lastRowNum = sheet.getLastRowNum();
for (int rowNum = firstRowNum; rowNum < lastRowNum; rowNum++) {
Row row = sheet.getRow(rowNum);
if (row == null) {
continue;
}
if (row.getLastCellNum() > -1) {
return row.getLastCellNum();
}
}
return -1;
}
}
I have a merge process in which several workbooks containing multiple worksheets are combined into a Master File. The sheets are group together by name.
Once the first workbook contents (sheets) are copied, the subsequent (2nd,3rd, 4th, etc) workbook contents (sheets) should skip the first row in each sheet and copy to the master file.
How would I iterate through the subsequent workbook sheets without
copying the first row (the headings)?
Simply put, I want to keep the heading (first row) from the first
iteration, then every workbook sheet afterwards that is copied. should skip the first row
(heading)
I've included the sample code below.
private static void copySheets( XSSFSheet newSheet, XSSFSheet sheet, boolean copyStyle){
int newRownumber = newSheet.getLastRowNum() + 1;
int maxColumnNum = 0;
Map<Integer, XSSFCellStyle> styleMap = (copyStyle) ? new HashMap<Integer, XSSFCellStyle>() : null;
for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
XSSFRow srcRow = sheet.getRow(i);
XSSFRow destRow = newSheet.createRow(i + newRownumber);
if (srcRow != null) {
//copyRow(newWorkbook, sheet, newSheet, srcRow, destRow, styleMap);
copyRow(sheet, newSheet, srcRow, destRow, styleMap);
if (srcRow.getLastCellNum() > maxColumnNum) {
maxColumnNum = srcRow.getLastCellNum();
}
}
}
for (int i = 0; i <= maxColumnNum; i++) {
newSheet.setColumnWidth(i, sheet.getColumnWidth(i));
}
}
public static void merge(File file) throws IOException {
XSSFWorkbook book = new XSSFWorkbook();
String directoryName = "C: users\\documents";
File directory = new File(directoryName);
File[] fList = directory.listFiles();
for (File file1 : fList){
if (file1.isFile()){
String ParticularFile = file1.getName();
File(directoryName+"\\"+ParticularFile));
FileInputStream fin = new FileInputStream(new File(directoryName+"\\"+ParticularFile));
XSSFWorkbook b = new XSSFWorkbook(fin);
INTERGRATED CODE
public static void merge(File file) throws IOException {
XSSFWorkbook book = new XSSFWorkbook();
System.out.println(file.getName());
String directoryName = "C:\\ Users\\Documents";
File directory = new File(directoryName);
File[] fList = directory.listFiles();
Boolean doNotReadHeaders = false;
Integer fileCount = 0;
for (File file1 : fList){
if (file1.isFile()){
doNotReadHeaders = (fileCount == 0) ? false : true;
String ParticularFile = file1.getName();
XSSFSheet sheet = b.getSheetAt(0);
for (int i = 1; i < (doNotReadHeaders ? sheet2.getPhysicalNumberOfRows() - 1 : sheet.getPhysicalNumberOfRows()); i++) { //Skipping headers only for the first workbook
Row row = sheet.getRow(ii);
if (row != null) {
for (int i = 0; i < b.getNumberOfSheets(); i++) {
XSSFSheet sheet = book.getSheet(b.getSheetName(i));
if (sheet == null)
sheet = book.createSheet(b.getSheetName(i));
for(int worksheetIndex = 0; worksheetIndex<b.getNumberOfSheets(); worksheetIndex++)
{
b.setSheetName(worksheetIndex, worksheetName);
System.out.println("test "+ worksheetIndex+ " " + worksheetName);
}
copySheets(sheet, b.getSheetAt(i));
}
}
try {
writeFile(book, file);
}catch(Exception e) {
e.printStackTrace();
}
}
}
for(int i = 1; i < sheet.getPhysicalNumberOfRows() - 1 ; i++){
Row row = sheet.getRow(i);
if(row != null){
// process your row
}
}
This way you can skip your heading and can read up to the rows which are not empty!
EDIT - If you have a list of workbooks to read, you can manage a check to read headers only for the first workbook, not for remaining workbooks.
Boolean doNotReadHeaders = false;
for (int f = 0; f < filesToReadCount; f++) {
doNotReadHeaders = (f == 0) ? false : true;
XSSFWorkbook workbook = new XSSFWorkbook(inputStream); // retrieve input stream acc. to your file lists
XSSFSheet sheet = workbook.getSheetAt(0);
for (int i = 1; i < (doNotReadHeaders ? sheet.getPhysicalNumberOfRows() - 1 : sheet.getPhysicalNumberOfRows()); i++) { //Skipping headers only for the first workbook
Row row = sheet.getRow(i);
if (row != null) {
// process your row
}
}
}
EDIT -
public static void merge(File file) throws IOException {
XSSFWorkbook book = new XSSFWorkbook();
String directoryName = "C: users\\documents";
File directory = new File(directoryName);
File[] fList = directory.listFiles();
Boolean doNotReadHeaders = false;
Integer fileCount = 0;
for (File file1: fList) {
if (file1.isFile()) {
doNotReadHeaders = (fileCount == 0) ? false : true;
String ParticularFile = file1.getName();
FileInputStream fin = new FileInputStream(new File(directoryName + "\\" + ParticularFile));
XSSFWorkbook workbook = new XSSFWorkbook(fin);
XSSFSheet sheet = workbook.getSheetAt(0);
for (int i = 1; i < (doNotReadHeaders ? sheet.getPhysicalNumberOfRows() - 1 : sheet.getPhysicalNumberOfRows()); i++) { //Skipping headers only for the first workbook
Row row = sheet.getRow(i);
if (row != null) {
// process your row
}
}
fileCount++;
}
}
}
I just integrated your code with mine.
EDIT - Final Code
private static void copySheets(XSSFSheet newSheet, XSSFSheet sheet, boolean doNotReadHeaders, boolean copyStyle) {
int newRownumber = newSheet.getLastRowNum() + 1;
int maxColumnNum = 0;
Map< Integer, XSSFCellStyle > styleMap = (copyStyle) ? new HashMap< Integer, XSSFCellStyle >() : null;
int FIRST_ROW_TO_GET = doNotReadHeaders ? 1 : 0;
for (int ii = FIRST_ROW_TO_GET; ii < sheet.getLastRowNum(); ii++) {
XSSFRow row = sheet.getRow(ii);
if (row != null) {
// The whole row is blank
//continue;
} else {
for (int i = (doNotReadHeaders ? sheet.getFirstRowNum() + 1 : sheet.getFirstRowNum()); i < (doNotReadHeaders ? sheet.getPhysicalNumberOfRows() -1 : sheet.getPhysicalNumberOfRows()); i++) {
XSSFRow srcRow = sheet.getRow(i);
XSSFRow destRow = newSheet.createRow(i + newRownumber);
if (srcRow != null) {
//copyRow(newWorkbook, sheet, newSheet, srcRow, destRow, styleMap);
//copyRow(sheet, newSheet, srcRow, destRow, styleMap);
if (srcRow.getLastCellNum() > maxColumnNum) {
maxColumnNum = srcRow.getLastCellNum();
}
}
}
}
}
for (int i = 0; i <= maxColumnNum; i++) {
newSheet.setColumnWidth(i, sheet.getColumnWidth(i));
}
}
public static void merge(File file) throws IOException {
XSSFWorkbook book = new XSSFWorkbook();
String directoryName = "C: users\\documents";
File directory = new File(directoryName);
File[] fList = directory.listFiles();
Boolean doNotReadHeaders = false;
Integer fileCount = 0;
for (File file1: fList) {
if (file1.isFile()) {
doNotReadHeaders = (fileCount == 0) ? false : true;
String ParticularFile = file1.getName();
FileInputStream fin = new FileInputStream(new File(directoryName + "\\" + ParticularFile));
XSSFWorkbook workbook = new XSSFWorkbook(fin);
XSSFSheet sheet = workbook.getSheetAt(0);
for (int j = 0; j < workbook.getNumberOfSheets(); j++) {
XSSFSheet innerSheet = workbook.getSheet(workbook.getSheetName(j));
if (innerSheet == null)
innerSheet = workbook.createSheet(workbook.getSheetName(j));
String worksheetName = "Sample sheet ";
for (int worksheetIndex = 0; worksheetIndex < workbook.getNumberOfSheets(); worksheetIndex++) {
workbook.setSheetName(worksheetIndex, worksheetName + worksheetIndex);
System.out.println("test " + worksheetIndex + " " + worksheetName);
}
copySheets(sheet, workbook.getSheetAt(j),doNotReadHeaders,false);
}
fileCount++;
}
try {
writeFile(workbook, file1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Now run this and let me know.
i am using Apache POI for reading Excel rows and using as needed. In order to Enhance the script for better reusability, how can i search and find a String value in all sheets under Column A and read corresponding row. For Example in Sheet2 ColumnA i have Name called Peter and in ColumnB Date of birth of Peter is 12/18/1984. Can you give code sample to search Peter in ColumnA in Excel work book and return his Date of Birth from ColumnB? Below is the code i am using currently may not suit above criteria.
package com.Sample.GenericFunctionsLibrary;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
public class TestUtil {
public static Xls_Reader excel = null;
public static String path = "./XLFile/Data.xlsx";
public static String mailscreenshotpath;
public static String generateTimeStamp() {
Calendar cal = new GregorianCalendar();
int month = cal.get(Calendar.MONTH); // 3
int year = cal.get(Calendar.YEAR); // 2014
int sec = cal.get(Calendar.SECOND);
int min = cal.get(Calendar.MINUTE);
int date = cal.get(Calendar.DATE);
int day = cal.get(Calendar.HOUR_OF_DAY);
String timestamp = year + "_" + date + "_" + (month + 1) + "_" + day + "_" + min + "_" + sec;
return timestamp;
}
public static boolean isExecutable(String tcid) {
for (int rowNum = 2; rowNum <= excel.getRowCount("Credentials"); rowNum++) {
if (excel.getCellData("Credentials", "TestCase_Name", rowNum).equals(tcid)) {
if (excel.getCellData("Credentials", "runmode", rowNum).equalsIgnoreCase("Y")) {
return true;
} else {
return false;
}
}
}
return false;
}
public static Object[][] getData(String sheetName) {
int rows = excel.getRowCount(sheetName);
int cols = excel.getColumnCount(sheetName);
Object[][] data = new Object[rows - 1][cols];
for (int rowNum = 2; rowNum <= rows; rowNum++) { // 2
for (int colNum = 0; colNum < cols; colNum++) {
data[rowNum - 2][colNum] = excel.getCellData(sheetName, colNum, rowNum); // -2
}
}
return data;
}
public static void zip(String filepath) {
try {
File inFolder = new File(filepath);
File outFolder = new File("Reports.zip");
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outFolder)));
BufferedInputStream in = null;
byte[] data = new byte[1000];
String files[] = inFolder.list();
for (int i = 0; i < files.length; i++) {
in = new BufferedInputStream(new FileInputStream(inFolder.getPath() + "/" + files[i]), 1000);
out.putNextEntry(new ZipEntry(files[i]));
int count;
while ((count = in.read(data, 0, 1000)) != -1) {
out.write(data, 0, count);
}
out.closeEntry();
}
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// --------------------------------------Read Data From
// Excel------------------------------------
public static String[][] GetValue(String Pathfile, String sheetName, int startrow) throws IOException {
File excel = new File(Pathfile);
FileInputStream fis = new FileInputStream(excel);
#SuppressWarnings("resource")
XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet ws = wb.getSheet(sheetName);
// System.out.println(startrow);
int colNum = ws.getRow(startrow).getLastCellNum();
// System.out.println(colNum);
String[][] arrays = new String[1][colNum];
for (int i = 0; i < colNum; i++) {
XSSFRow row = ws.getRow(startrow);
XSSFCell cell = row.getCell(i);
arrays[0][i] = cellToString(cell);
// System.out.println(arrays[0][i]);
}
return arrays;
}
// private static String cellToString(XSSFCell cell) {
// Object result;
// int type = cell.getCellType();
//
// switch(type)
// {
// case 0:
// result = cell.getNumericCellValue();
// break;
// case 1:
// result = cell.getStringCellValue();
// break;
// default:
// throw new RuntimeException("there are no support for this type of cell");
// }
private static String cellToString(XSSFCell cell) {
Object result;
int type;
try {
type = cell.getCellType();
} catch (NullPointerException e) {
type = 2;
}
switch (type) {
case Cell.CELL_TYPE_NUMERIC:
DataFormatter formatter = new DataFormatter();
result = formatter.formatCellValue(cell);
break;
case Cell.CELL_TYPE_STRING:
result = cell.getStringCellValue();
break;
case Cell.CELL_TYPE_BLANK:
result = "";
break;
default:
throw new RuntimeException("there are no support for this type of cell");
}
//
return result.toString();
}
}
This method will take a String value for the name to search and return the address for the first record found in the column next to it, assuming that the name is in the first column and the address is in the second column. It will iterate over all sheets as asked. It returns empty String if name is not found. Try/catch block excluded for readability.
public static String findAddressByName(String nameToSearch) {
String fileLocation = "I:\\foo.xlsx";
XSSFWorkbook wb = new XSSFWorkbook(new File(fileLocation));
for (int sheetIndex = 0; sheetIndex < wb.getNumberOfSheets(); sheetIndex++) {
XSSFSheet sheet = wb.getSheetAt(sheetIndex);
for (int rowIndex = 0; rowIndex < sheet.getLastRowNum(); rowIndex++) {
XSSFRow row = sheet.getRow(rowIndex);
if (row != null && row.getCell(0).getStringCellValue().equals(nameToSearch)) {
return row.getCell(1).getRawValue();
}
}
}
return "";
}
I'm writing a program where I need to merge rows in Excel sheet. Currently, I'm able to merge the starting rows, but when coming to the end, I'm unable to know where it is going wrong. Below is my code.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
public class RowsMerge {
public static void main(String[] args) throws IOException {
FileInputStream fin = new FileInputStream(
new File("C:\\D\\Sheets\\Sample Sheets\\dummy.xls"));
HSSFWorkbook workbook = new HSSFWorkbook(fin);
HSSFSheet sheet = workbook.getSheetAt(0);
int row = sheet.getPhysicalNumberOfRows();
String currentLawName, currentCountry, currentAssociate, previousLawName, previousCountry, previousAssociate;
String currentPages, previousPages;
int startIndex = 1, finalIndex = 0, tempNum = 0;
System.out.println(row);
for (int i = 2; i < (row - 1); i++) {
currentAssociate = sheet.getRow(i).getCell(0).toString();
currentLawName = sheet.getRow(i).getCell(1).toString();
currentCountry = sheet.getRow(i).getCell(2).toString();
currentPages = sheet.getRow(i).getCell(3).toString();
previousAssociate = sheet.getRow(i - 1).getCell(0).toString();
previousLawName = sheet.getRow(i - 1).getCell(1).toString();
previousCountry = sheet.getRow(i - 1).getCell(2).toString();
previousPages = sheet.getRow(i - 1).getCell(3).toString();
if (currentAssociate.equals(previousAssociate) && currentCountry.equals(previousCountry)
&& currentLawName.equals(previousLawName) && currentPages.equals(previousPages)) {
finalIndex += 1;
} else {
sendRangeToMergeCells(startIndex, finalIndex, sheet);
startIndex = i;
finalIndex = 0;
}
}
FileOutputStream fileOut = new FileOutputStream("C:\\D\\Sheets\\Sample Sheets\\dummy.xls");
workbook.write(fileOut);
fileOut.close();
}
private static void sendRangeToMergeCells(int startIndex, int finalIndex, HSSFSheet sheet) {
System.out.println(startIndex + "\t" + (startIndex + finalIndex));
CellRangeAddress region = CellRangeAddress
.valueOf("D" + (startIndex + 1) + ":D" + ((startIndex + finalIndex) + 1));
sheet.addMergedRegion(region);
}
}
Below is my Excel Sheet
SourceExcel:
Current output:
Expected output:
Actually your merge logic is fine, it is your break logic (the logic which determines when to merge the rows) that is missing a bit.
If the last row in your spreadsheet matches the previous row, no merge will be performed because execution will follow the first branch of if (currentAssociate.equals(previousAssociate) && ... and the loop ends. You have to test for and execute the merge logic if necessary one last time after the for loop completes.
Add the following after your for loop:
if (finalIndex > 0) {
sendRangeToMergeCells(startIndex, finalIndex, sheet);
}
this will merge the last rows if necessary.
Exception in thread "main" java.lang.NullPointerException
at add.copy(add.java:69)
at add.main(add.java:33)
Hi guys, this is my first question I have asked so I'm sorry if I do it wrong. I am currently making a program that needs to read an Excel sheet and add it to an Excel workbook that already contains one sheet. I am doing the reading and writing in sections due to heap size errors. I can currently read and write each section successfully until the last section. When it tries to do the last section I get the error seen above.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class add {
public static void main(String[] args) throws IOException {
XSSFSheet sheet1=get();
int fRow = 0;
int lRow = 0;
int rownum = 0;
int addon = 0;
int num = 0;
int numi = 100/20;
num = numi + numi;
fRow = sheet1.getFirstRowNum();
lRow = 553;
copy(fRow,lRow,sheet1);
System.out.println("5%");
rownum = 129000;
addon = rownum/20;
for(int i=0;i<20;i++){
System.out.println(num + "%");
fRow = lRow;
lRow = lRow + addon;
copy(fRow,lRow,sheet1);
num = num + numi;
}
//System.out.println("100%");
}
public static void copy(int fRow, int lRow, XSSFSheet sheet1) throws IOException{
File excel2 = new File ("C:/Users/Colm/Documents/windmill_proj/excels/testing.xlsx");
FileInputStream bis = new FileInputStream(excel2);
XSSFWorkbook workbook = null;
workbook = new XSSFWorkbook(bis);
XSSFSheet mySheet = null;
XSSFRow row1 = null;
XSSFRow row2 = null;
XSSFCell cell2 = null;
XSSFCell cell1 = null;
int fCell = 0;
int lCell = 0;
String sheetname1 = sheet1.getSheetName();
int sindex = workbook.getSheetIndex(sheetname1);
if(sindex==-1){
mySheet = workbook.createSheet(sheet1.getSheetName());
System.out.println("sheet made");
}
else{
mySheet = workbook.getSheetAt(1);
}
for (int iRow = fRow; iRow <= lRow; iRow++)
{
row1 = sheet1.getRow(iRow);
row2 = mySheet.createRow(iRow);
fCell = row1.getFirstCellNum();
lCell = row1.getLastCellNum();
for (int iCell = fCell; iCell < lCell; iCell++)
{
cell2 = row1.getCell(iCell);
cell1 = row2.createCell(iCell);
cell1.setCellType(cell2.getCellType());
// Set the cell data value
switch (cell2.getCellType()) {
case org.apache.poi.ss.usermodel.Cell.CELL_TYPE_BLANK:
cell1.setCellValue(cell2.getStringCellValue());
break;
case org.apache.poi.ss.usermodel.Cell.CELL_TYPE_BOOLEAN:
cell1.setCellValue(cell2.getBooleanCellValue());
break;
case org.apache.poi.ss.usermodel.Cell.CELL_TYPE_ERROR:
cell1.setCellErrorValue(cell2.getErrorCellValue());
break;
case org.apache.poi.ss.usermodel.Cell.CELL_TYPE_FORMULA:
cell1.setCellFormula(cell2.getCellFormula());
break;
case org.apache.poi.ss.usermodel.Cell.CELL_TYPE_NUMERIC:
cell1.setCellValue(cell2.getNumericCellValue());
break;
case org.apache.poi.ss.usermodel.Cell.CELL_TYPE_STRING:
cell1.setCellValue(cell2.getRichStringCellValue());
break;
}
}
}
FileOutputStream out = new FileOutputStream("C:/Users/Colm/Documents/windmill_proj/excels/testing.xlsx");
workbook.write(out);
out.flush();
out.close();
workbook.close();
bis.close();
}
public static XSSFSheet get() throws IOException{
File fn = new File ("C:/Users/Colm/Documents/windmill_proj/excels/testing2.xlsx");
FileInputStream biss = new FileInputStream(fn);
XSSFWorkbook workbook = null;
workbook = new XSSFWorkbook(biss);
biss.close();
XSSFWorkbook myWorkBook = new XSSFWorkbook();
XSSFSheet sheet = null;
XSSFRow row = null;
XSSFCell cell = null;
XSSFSheet mySheet = null;
XSSFRow myRow = null;
XSSFCell myCell = null;
int sheets = 1;
int fCell = 0;
int lCell = 0;
int fRow = 0;
int lRow = 0;
for (int iSheet = 0; iSheet < sheets; iSheet++) {
sheet = workbook.getSheetAt(iSheet);
if (sheet != null) {
mySheet = myWorkBook.createSheet(sheet.getSheetName());
fRow = sheet.getFirstRowNum();
lRow = sheet.getLastRowNum();
for (int iRow = fRow; iRow <= lRow; iRow++) {
row = sheet.getRow(iRow);
myRow = mySheet.createRow(iRow);
if (row != null) {
fCell = row.getFirstCellNum();
lCell = row.getLastCellNum();
for (int iCell = fCell; iCell < lCell; iCell++) {
cell = row.getCell(iCell);
myCell = myRow.createCell(iCell);
if (cell != null) {
myCell.setCellType(cell.getCellType());
switch (cell.getCellType()) {
case XSSFCell.CELL_TYPE_BLANK:
myCell.setCellValue("");
break;
case XSSFCell.CELL_TYPE_BOOLEAN:
myCell.setCellValue(cell.getBooleanCellValue());
break;
case XSSFCell.CELL_TYPE_ERROR:
myCell.setCellErrorValue(cell.getErrorCellValue());
break;
case XSSFCell.CELL_TYPE_FORMULA:
myCell.setCellFormula(cell.getCellFormula());
break;
case XSSFCell.CELL_TYPE_NUMERIC:
myCell.setCellValue(cell.getNumericCellValue());
break;
case XSSFCell.CELL_TYPE_STRING:
myCell.setCellValue(cell.getStringCellValue());
break;
default:
myCell.setCellFormula(cell.getCellFormula());
}
}
}
}
}
}
}
myWorkBook.close();
workbook.close();
System.out.println("done");
return mySheet;
}
}
If someone could suggest what might be the problem or what way I could test to try find the problem I would be very grateful.
Thanks!