I'm using the Apache POi HSSF library to import and export an Excel table to my application (tableview). I want to delete from Java a Row in Excel with a specific ID. It works. My Problem is, after i delete a row there are a empty row and it delete more than the selected row. Could everybody help?
FileInputStream inp = new FileInputStream(
"...............";
HSSFWorkbook wb = (HSSFWorkbook) WorkbookFactory.create(inp);
HSSFSheet sheet = wb.getSheetAt(0);
String selectedid = auftragTabelle.getSelectionModel().getSelectedItem().getId();
int rowIndex = 0;
int lastRowNum = sheet.getLastRowNum();
for (Row row : sheet) {
for (Cell cell : row) {
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
if (cell.getRichStringCellValue().getString().trim().equals(selectedid)) {
rowIndex = cell.getRowIndex();
}
}
}
}
if (rowIndex >= 0 && rowIndex < lastRowNum) {
sheet.shiftRows(rowIndex, lastRowNum, -1);
}
if (rowIndex <= lastRowNum) {
HSSFRow removingRow = sheet.getRow(rowIndex);
if (removingRow != null) {
sheet.removeRow(removingRow);
}
}
OutputStream out = new FileOutputStream(
"............";
wb.write(out);
out.close();
}
Here's an example of how I would do it:
public static void main(String[] args) throws InvalidFormatException, IOException {
FileInputStream inp = new FileInputStream(FILENAME);
HSSFWorkbook wb = (HSSFWorkbook) WorkbookFactory.create(inp);
HSSFSheet sheet = wb.getSheetAt(0);
String selectedid = "3";
int rowIndex = getRowIndexOfId(sheet, selectedid);
removeRow(sheet, rowIndex);
OutputStream out = new FileOutputStream(FILENAME);
wb.write(out);
out.close();
}
private static int getRowIndexOfId(HSSFSheet sheet, String selectedid) {
DataFormatter formatter = new DataFormatter();
for (Row row : sheet) {
for (Cell cell : row) {
if (formatter.formatCellValue(cell).trim().equals(selectedid)) {
return row.getRowNum();
}
}
}
return -1;
}
private static void removeRow(HSSFSheet sheet, int rowIndex) {
if (rowIndex >= 0) {
sheet.removeRow(sheet.getRow(rowIndex));
if(rowIndex < sheet.getLastRowNum()) {
sheet.shiftRows(rowIndex + 1, sheet.getLastRowNum(), -1);
}
}
}
A few comments:
You can use the class DataFormatter to format the cell values (so you can compare any cell value)
I - like you - compare any cell in a cell; the typical use case for me would be to search the first col of each row to find the id. SO if you want that, adjust the code accordingly.
I did the shift row in the end, which should work better.
Related
I have an Excel file which needs filtering on a specific column.
String fileName = "filepath";
String cellContent = "Automation";
int rownr = 0;
int colnr = 0; //column from which you need data to store in array list
InputStream input = new FileInputStream(fileName);
XSSFWorkbook wb = new XSSFWorkbook(input);
XSSFSheet sheet = wb.getSheetAt(0);
List filteredCol = new ArrayList();
filteredCol = findRow(sheet, cellContent);
if (filteredCol != null) {
for (Iterator iter = filteredCol.iterator(); iter.hasNext(); ) {
System.out.println(iter.next());
}
}
private static List findRow(HSSFSheet sheet, String cellContent) {
List filter=new ArrayList();
for (Row row : sheet) {
for (Cell cell : row) {
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
if (cell.getRichStringCellValue().getString().trim().equals(cellContent)) {
//System.out.println("Row numbers are"+row.getRowNum());
int rownumber=row.getRowNum();
//return row.getRowNum();
XSSFRow row1 = sheet.getRow(rownumber);
XSSFCell cell1 = row1.getCell(0);
filter.add(cell1);
}
}
}
}
return filter;
}
I am getting number format exception on this codeline:
"cell.getRichStringCellValue().getString().trim().equals(cellContent)"
I have read others questions similar to mine, but I miss something as none of my rows are deleted... After a lot of tries I have ended to the following code..
I want to delete all the rows except the 1st line, that's why the counter starts from 1...
//...
FileInputStream file = new FileInputStream(new File("E:\\products.xls"));
HSSFWorkbook workbook = new HSSFWorkbook(file);
HSSFSheet sheet = workbook.getSheetAt(0);
for(int i=1; i<= sheet.getLastRowNum(); i++){
Row row = sheet.getRow(i);
deleteRow(sheet, row);
}
file.close();
FileOutputStream outFile = new FileOutputStream(new File("E:\\products.xls"));
workbook.write(outFile);
outFile.close();
//...
//The delete method...
private void deleteRow(HSSFSheet sheet, Row row) {
int lastRowNum = sheet.getLastRowNum();
int rowIndex = row.getRowNum();
if(rowIndex >= 0 && rowIndex < lastRowNum){
sheet.shiftRows(rowIndex + 1, lastRowNum, -1);
}
if(rowIndex == lastRowNum){
Row removingRow = sheet.getRow(rowIndex);
if(removingRow != null){
sheet.removeRow(removingRow);
System.out.println("Deleting.... ");
}
}
}
I don't get any error, but none row is deleted.
UPDATE
As you mentioned below, I wasn't saving the file... I updated the code above where now I save it! However, some of my rows are deleted and not all of them...
Any ideas why is this happening?
Yuor code works perfectly , only one thing missing : write the result to file ...
wb.write(new FileOutputStream(new File("E:\\products.xls")));
Complete working example:
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.usermodel.Row;
public class Main {
public Main() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) throws IOException {
FileInputStream file = null;
HSSFWorkbook wb = null;
FileOutputStream out = null;
try{
file = new FileInputStream(new File("E:\\products.xls"));
wb = new HSSFWorkbook(file);
HSSFSheet sheet = wb.getSheetAt(0);
for(int i=1; i<= sheet.getLastRowNum(); i++){
Row row = sheet.getRow(i);
deleteRow(sheet, row);
}
out = new FileOutputStream(new File("E:\\products.xls"));
wb.write(out);
}
catch(Exception e){}
finally{
if(file!=null)
file.close();
if(out!=null)
out.close();
if(wb!=null)
wb.close();
}
}
public static void deleteRow(HSSFSheet sheet, Row row) {
int lastRowNum = sheet.getLastRowNum();
int rowIndex = row.getRowNum();
if(rowIndex >= 0 && rowIndex < lastRowNum){
sheet.shiftRows(rowIndex + 1, lastRowNum, -1);
}
if(rowIndex == lastRowNum){
Row removingRow = sheet.getRow(rowIndex);
if(removingRow != null){
sheet.removeRow(removingRow);
System.out.println("Deleting.... ");
}
}
}
}
The only problem in your code its that the beavhiour its not what you expect from the method deleteRow(..) i modified your method in this way :
public static void deleteRow(HSSFSheet sheet, Row row) {
int lastRowNum = sheet.getLastRowNum();
if(lastRowNum !=0 && lastRowNum >0){
int rowIndex = row.getRowNum();
Row removingRow = sheet.getRow(rowIndex);
if(removingRow != null){
sheet.removeRow(removingRow);
System.out.println("Deleting.... ");
}
}
}
If there is only one row in the file , you will not delete , if there are more , you delete all the rows except the first one .
You forgot to save your workbook apparently...
workbook.Save(path)
I think you forgot save changes.
I have data in the above format in an excel file , I want to edit it as follows:
I have used the following code :
public void editExcelTemplate() throws FileNotFoundException, IOException
{
InputStream ExcelFileToRead = new FileInputStream("file.xls");
XSSFWorkbook wb = new XSSFWorkbook(ExcelFileToRead);
XSSFSheet sheet = wb.getSheetAt(0);
int rows = sheet.getPhysicalNumberOfRows();
String cmp = "none";
for(int i=0;i<rows;i++)
{
Row row = sheet.getRow(i);
int col =row.getPhysicalNumberOfCells();
int colIndex = 1;
int v=0;
for(int j=0;j<col;j++)
{
String content = row.getCell(j).getStringCellValue();
if(!(content == cmp) && !(content.equals("none")))
{
if(!(cmp.equals("none")))
{
System.out.println("content: "+content);
System.out.println("cmp: "+cmp);
v= j;
System.out.println("row : "+i+"colst : "+(colIndex)+"colend : "+v);
if(!( v-colIndex == 0) && v>0)
{
System.out.println("row : "+i+"colst : "+(colIndex)+"colend : "+v);
sheet.addMergedRegion(new CellRangeAddress(i,i,colIndex-1,v-1));
System.out.println("merged");
}
}
}
if(!(content == cmp))
{
colIndex = v+1;
}
cmp = content;
}
}
FileOutputStream excelOutputStream = new FileOutputStream(
"file.xls");
wb.write(excelOutputStream);
excelOutputStream.close();
}
I endedup getting the following output :
Can anybody help me get an appropriate output ? The main purpose is to merge the cells with common data in the entire proces.
i have an excel file with merged and formula cell which is using the VLOOKUP(B16,Data!$A$2:$C$7,3,0). In specific cell $40 is appearing as value. but when i try to read the value it is reading only 40 and skipping the $ part.
public static void main(String[] args) {
try {
String excelFilePath = "D:\\test\\1_sample1_UA Logo Order form update on 2016-12-06.xls";
InputStream input = new BufferedInputStream(new FileInputStream(
excelFilePath));
POIFSFileSystem fs = new POIFSFileSystem(input);
HSSFWorkbook workbook = new HSSFWorkbook(fs);
workbook.setForceFormulaRecalculation(true);
Sheet sheet = workbook.getSheetAt(3);
Row row = sheet.getRow(15);
Cell cell = row.getCell(7);
for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
CellRangeAddress region = sheet.getMergedRegion(i); // Region of
// merged
// cells
int colIndex = region.getFirstColumn();
int rowNum = region.getFirstRow();
if (region.isInRange(15, 7)) {
CellReference cellReference = new CellReference("H15");
Row row2 = sheet.getRow(cellReference.getRow());
Cell cell2 = row2.getCell(cellReference.getCol());
// formulla evaluato
FormulaEvaluator forEvaluator = workbook
.getCreationHelper().createFormulaEvaluator();
workbook.getCreationHelper().createFormulaEvaluator()
.evaluateAll();
workbook.setForceFormulaRecalculation(true);
CellValue cellValue = forEvaluator.evaluate(cell2);
System.out.println("cell string value2 :: "
+ cellValue.formatAsString());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
I'm writing a program that does the following tasks:
Cleans up Excel files (i.e. remove rows based on a condition).
Add data from notepad to a new Excel (say Result Excel).
Add the data from Cleaned Excel files to the Result Excel.
Below is my code:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.io.FilenameUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
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.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class TextToExcelMultiple {
static int counter = 1;
public static void main(String[] args) throws Exception {
File mainFolder = new File("C:\\D\\Mypath\\New");
File[] files;
int rowCount = 0;
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("Result");
CellStyle style = workbook.createCellStyle();// Create style
Font font = workbook.createFont();// Create font
font.setBoldweight(Font.BOLDWEIGHT_BOLD);// Make font bold
style.setAlignment(CellStyle.ALIGN_CENTER);
style.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
style.setFillPattern(CellStyle.SOLID_FOREGROUND);
style.setFont(font);// set it to bold
Row row;
Cell cell;
row = sheet.createRow(rowCount);
cell = row.createCell(0);
cell.setCellValue("NAME");
cell = row.createCell(1);
cell.setCellValue("TITLE");
cell = row.createCell(2);
cell.setCellValue("FIRM");
cell = row.createCell(3);
cell.setCellValue("ADDRESS 1");
cell = row.createCell(4);
cell.setCellValue("ADDRESS 2");
cell = row.createCell(5);
cell.setCellValue("ADDRESS 3");
cell = row.createCell(6);
cell.setCellValue("CITY");
cell = row.createCell(7);
cell.setCellValue("STATE");
cell = row.createCell(8);
cell.setCellValue("POSTAL CODE");
cell = row.createCell(9);
cell.setCellValue("COUNTRY");
cell = row.createCell(10);
cell.setCellValue("PHONE");
cell = row.createCell(11);
cell.setCellValue("FAX");
cell = row.createCell(12);
cell.setCellValue("URL");
cell = row.createCell(13);
cell.setCellValue("ISN");
for (int i = 0; i < row.getLastCellNum(); i++) {
row.getCell(i).setCellStyle(style);
}
rowCount = 1;
if (mainFolder.isDirectory()) {
files = mainFolder.listFiles();
for (File file : files) {
if (file.isDirectory()) {
files = file.listFiles();
for (File finalFile : files) {
String ext = FilenameUtils.getExtension(finalFile.getAbsolutePath());
if ((ext.contains("xls") && finalFile.getName().toLowerCase().contains("detail"))) {
cleanUpFile(finalFile);
}
}
for (File finalFile : files) {
String ext = FilenameUtils.getExtension(finalFile.getAbsolutePath());
if ((ext.equals("txt") && finalFile.getName().contains("brief"))
|| (ext.contains("xls") && finalFile.getName().toLowerCase().contains("detail"))) {
int rowNumber = writeData(finalFile, sheet, rowCount, workbook);
rowCount = rowNumber;
}
}
}
}
}
FileOutputStream outputStream = new FileOutputStream("C:\\D\\Mihir\\new.xls");
workbook.write(outputStream);
outputStream.close();
}
private static int writeData(File file, XSSFSheet sheet, int rowCount, XSSFWorkbook workbook) throws Exception {
FileInputStream fileInputStream = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fileInputStream));
String x;
Row row;
Cell cell;
String ext = FilenameUtils.getExtension(file.getAbsolutePath() + " \t " + file.getName());
if (!ext.contains("xls")) {
while ((x = br.readLine()) != null) {
if (!(x.contains("NAME"))) {
row = sheet.createRow(rowCount);
String[] namesList = x.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)", -1);
int columnCount = 0;
for (String name : namesList) {
cell = row.createCell(columnCount);
cell.setCellValue(name.replace("\"", ""));
columnCount += 1;
}
rowCount += 1;
}
}
}
if (ext.contains("xls")) {
int result = appendDataToExcel(file, workbook, rowCount, counter);
counter = result;
}
br.close();
fileInputStream.close();
return rowCount;
}
private static void cleanUpFile(File file) throws Exception {
System.out.println(file.getAbsolutePath());
FileInputStream fin = new FileInputStream(new File(file.getAbsolutePath()));
Workbook wb = new XSSFWorkbook(fin);
Sheet sheet = wb.getSheetAt(0);
Cell cell;
for (int i = 0; i <= sheet.getLastRowNum(); i++) {
cell = sheet.getRow(i).getCell(1);
if (cell == null) {
sheet.removeRow(sheet.getRow(i));
int rowIndex = i;
int lastRowNum = sheet.getLastRowNum();
if (rowIndex >= 0 && rowIndex <= lastRowNum) {
sheet.shiftRows(rowIndex + 1, lastRowNum, -1);
}
}
}
fin.close();
FileOutputStream outFile = new FileOutputStream(new File(file.getAbsolutePath()));
wb.write(outFile);
wb.close();
outFile.close();
}
private static int appendDataToExcel(File file, XSSFWorkbook workbook, int rowCount, int counter) throws Exception {
String path = file.getAbsolutePath();
FileInputStream fin = new FileInputStream(new File(path));
XSSFWorkbook wb = new XSSFWorkbook(fin);
XSSFSheet sheet1 = wb.getSheetAt(0);
int noOfRows = sheet1.getPhysicalNumberOfRows();
XSSFSheet sheet = workbook.getSheetAt(0);
Cell cell;
XSSFRow row;
for (int i = 1; i < noOfRows; i++) {
row = sheet.getRow(counter);
cell = row.getCell(13);
if (cell == null || cell.getCellType() == Cell.CELL_TYPE_BLANK) {
cell = row.createCell(13);
}
Cell cell1 = sheet1.getRow(i).getCell(1);
if (cell1 != null && !cell1.equals("")) {
cell.setCellValue(sheet1.getRow(i).getCell(1).toString() + "\t" + counter);
}
counter++;
}
wb.close();
fin.close();
counter = rowCount;
return (counter);
}
}
Previously I used to call cleanUpFile(file) method, And this use to give me the below exception.
Later on I tried to first clean files and then run the program on the cleaned files But still I get the same exception:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.io.ByteArrayOutputStream.grow(Unknown Source)
at java.io.ByteArrayOutputStream.ensureCapacity(Unknown Source)
at java.io.ByteArrayOutputStream.write(Unknown Source)
at org.apache.poi.openxml4j.opc.internal.MemoryPackagePartOutputStream.write(MemoryPackagePartOutputStream.java:88)
at org.apache.xmlbeans.impl.store.Cursor._save(Cursor.java:590)
at org.apache.xmlbeans.impl.store.Cursor.save(Cursor.java:2544)
at org.apache.xmlbeans.impl.values.XmlObjectBase.save(XmlObjectBase.java:223)
at org.apache.poi.xssf.usermodel.XSSFSheet.write(XSSFSheet.java:2972)
at org.apache.poi.xssf.usermodel.XSSFSheet.commit(XSSFSheet.java:2927)
at org.apache.poi.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:323)
at org.apache.poi.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:327)
at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:195)
at TextToExcelMultiple.main(TextToExcelMultiple.java:100)
And when I click on at TextToExcelMultiple.main(TextToExcelMultiple.java:100) it points out to workbook.write(outputStream);
I've got really big set of files.
One more thing: when I comment out the below block and run it, it works fine:
for (File finalFile : files) {
String ext = FilenameUtils.getExtension(finalFile.getAbsolutePath());
if ((ext.equals("txt") && finalFile.getName().contains("brief"))
|| (ext.contains("xls") && finalFile.getName().toLowerCase().contains("detail"))) {
int rowNumber = writeData(finalFile, sheet, rowCount, workbook);
rowCount = rowNumber;
}
}
Going through some other SO posts, I've added the below in my arguments:
-Xms1100m -Xmx1100m
When I try to increase heap memory -Xms1150m -Xmx2048m it gives me below error:
Error occurred during initialization of VM
Could not reserve enough space for 2097152KB object heap
Since my free memory available is around 1150MB:
Also if I deploy this as a swing app in my client's system, what all should be taken care before doing so?
How can I run this full program without facing the exception?