I'm working on POI application in order to manipulate excel file.
In fact the user is giving a formula and files and I am applying the formula on a output file.The formula have to modify the value of the column on the cell.
For example on the columns B, I want to apply on all my column a formula.
The user is giving to me LEFT(x,2), and I have to apply this to all the columns.
(x is defining all the columns)
But when I am applying the formula I got the formula as a String. I try to pass the cell value at the formula but of course it is not working...
I think I should copy all my data into a another excel file, work on it and copy paste them in the output file or their is another way ?
Regards,
Code:
for (int i = 0; i < cell[0].length; i++){ //Checking the header
for (int j = 0; j < ruleArray.length; j++){ //Checking the Header of the array with the rule to apply
if (cell[0][i].toString().equals(ruleArray[j][0])){ //Comparing
String testF = ruleArray[j][1];
if (testF.contains("X") || testF.contains("x")){ //Replacing X with value for the formula
for (int k = 0; k < cell.length; k++){
indexT = cell[0][i].getColumnIndex();
indexC = cell[k][i].getRowIndex()+1;
String colLetter = CellReference.convertNumToColString(indexT);
formula = testF.replace("x", colLetter+indexC);
cell[k][i].setCellType(CellType.FORMULA);
cell[k][i].setCellFormula(formula);
}
}
}
}
}
I am not rewrite your code but you can take a help from this. Create a excel file with column City and Formula and then run this code. I have attached some snapshot of excel file. I thin kit will help you. LEFT(X,2) only parse first two char from a string
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class TestProblem
{
public static void main(String[] args) throws IOException {
InputStream inp = null;
inp = new FileInputStream("E:\\Projects\\PoiAdvanceExample\\stackProblem.xlsx");
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt(0);
int rowsCount = sheet.getLastRowNum();
int columnCount = sheet.getRow(0).getLastCellNum();
String[][] inputData = new String[rowsCount+1][columnCount];
for (int i = 0; i <= rowsCount; i++) {
Row row = sheet.getRow(i);
int colCounts = row.getLastCellNum();
for (int j = 0; j < colCounts; j++) {
Cell cell = row.getCell(j);
if(cell.getCellType() == CellType.NUMERIC) {
inputData[i][j] = Double.toString(cell.getNumericCellValue());
}
if(cell.getCellType() == CellType.FORMULA) {
inputData[i][j] = cell.getCellFormula();
}
if(cell.getCellType() == CellType.STRING) {
inputData[i][j] = cell.getStringCellValue();
}
}
}
writeData(inputData);
}
private static void writeData(String[][] inputData) throws IOException {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
int r = 0;
for (String[] dataRow : inputData) {
Row row = sheet.createRow(r++);
int column = 0;
for (String dataCell : dataRow) {
Cell cell = row.createCell(column++);
if (r == 1 || column == 1) cell.setCellValue(dataCell);
else if (column == 2) {
CellReference cellReference = new CellReference(cell);
String thisR = cellReference.getCellRefParts()[1];
cell.setCellFormula("LEFT(A" + thisR + ",2)");
}
}
}
FileOutputStream fileOut = new FileOutputStream("stackProblem.xlsx");
workbook.write(fileOut);
workbook.close();
}
}
Excel file before run will be like this.
Excel file after run this code will be like this.
Related
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. How can i change/enhance this code to Insert/Set value/Text in the third column?
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 have tried various ways of removing the index out of bound error by changing the upper limits of the array.But the error persists. Where am I going wrong?
Screenshot of my excel sheet
My program reads values(all rows) in the first column of excel sheet and finds the maximum value. Then based on the maximum value,criteria are formulated and the values are classified as Low,Medium,High and written back into a new excel sheet.
import java.io.FileInputStream;
import java.io.IOException;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import java.io.*;
import java.util.*;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.Label;
import jxl.write.WriteException;
public class Bus3{
List<String> numbusarray = new ArrayList<String>();
List<String> numcommutersarray = new ArrayList<String>();
List<String> numcommercialarray = new ArrayList<String>();
static WritableWorkbook workbook;
static WritableSheet wSheet;
public void readExcel() throws BiffException, IOException, WriteException//method to read contents form excel
{
String FilePath = "Bus1.xls";
Scanner sc = new Scanner(System.in);
int max=0;
FileInputStream fs = new FileInputStream(FilePath);
Workbook wb = Workbook.getWorkbook(fs);
Sheet sh = wb.getSheet("Bus1");// TO get the access to the sheet
int totalNoOfRows = sh.getRows();// To get the number of rows present in sheet
int totalNoOfCols = sh.getColumns();// To get the number of columns present in sheet
System.out.println(totalNoOfRows);
//adding excel contents from every column to arraylist
for (int row = 1; row <totalNoOfRows; row++)
{
numbusarray.add(sh.getCell(2, row).getContents());
}
for (int row = 1; row <totalNoOfRows; row++)
{
numcommutersarray.add(sh.getCell(3, row).getContents());
}
for (int row = 1; row <totalNoOfRows; row++)
{
numcommercialarray.add(sh.getCell(4, row).getContents());
}
//to find maximum of numbusarray
max=Integer.parseInt(numbusarray.get(0));
for (int row = 1; row < totalNoOfRows-1; row++)
{
if(!(numbusarray.get(row)).isEmpty())
{
int intNumber=Integer.parseInt(numbusarray.get(row));
if(intNumber>max)
{
max=intNumber;
//System.out.println(max);
}
}
}
System.out.println(max);
WritableWorkbook workbook = Workbook.createWorkbook(new File("sampletestfile.xls"));
WritableSheet wSheet = workbook.getSheet(0);
int increment=max/3;
int a=increment;
int b=a+increment;
int c=b+increment;
for (int row = 0; row < totalNoOfRows-1; row++)
{
if(!(numbusarray.get(row)).isEmpty())
{
int compare=Integer.parseInt(numbusarray.get(row));
if(compare<=a)
{Label label= new Label(0, row, "Low");//column,row,strngdata
wSheet.addCell(label);}
else if((compare>a)&&(compare<=b))
{Label label= new Label(0, row, "Medium");//column,row,strngdata
wSheet.addCell(label);}
else
{Label label= new Label(0, row, "High");//column,row,strngdata
wSheet.addCell(label);}
}
}
/*Iterator itr=numbusarray.iterator(); //to print arraylist demo
while(itr.hasNext()){
System.out.println(itr.next());
}*/
}//end of method to read contents from excel
//to close file
public static void closeFile()
{
try {
// Closing the writable work book
workbook.write();
workbook.close();
// Closing the original work book
} catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String args[]) throws BiffException, IOException, WriteException //main class
{
Bus3 DT = new Bus3();
DT.readExcel();
Bus3.closeFile();
}//end of main class
}
It is because your sh Sheet.class object doesn't have cells with column = 4.
This should fix it:
for (int row = 1; row < totalNoOfRows; row++) {
numbusarray.add(sh.getCell(1, row).getContents());
}
for (int row = 1; row < totalNoOfRows; row++) {
numcommutersarray.add(sh.getCell(2, row).getContents());
}
for (int row = 1; row < totalNoOfRows; row++) {
numcommercialarray.add(sh.getCell(3, row).getContents());
}
LAST EDIT:
for (int row = 1; row < totalNoOfRows; row++) {
numbusarray.add(sh.getCell(1, row).getContents());
}
for (int row = 1; row < totalNoOfRows; row++) {
numcommutersarray.add(sh.getCell(2, row).getContents());
}
for (int row = 1; row < totalNoOfRows; row++) {
numcommercialarray.add(sh.getCell(3, row).getContents());
}
// to find maximum of numbusarray
max = 0;
for (int row = 1; row < totalNoOfRows; row++) {
if (!(numbusarray.get(row - 1)).isEmpty()) {
int intNumber = Integer.parseInt(numbusarray.get(row - 1));
if (intNumber > max) {
max = intNumber;
System.out.println("max: " + max);
}
}
}
System.out.println(max);
workbook = Workbook.createWorkbook(new File("sampletestfile.xls"));
WritableSheet wSheet = workbook.createSheet("name", 0);
It does not look like a very complex problem.
Index out of bounds means that you are trying to access a position in the array that does not exists.
Watch your numbusarray variable, probably row is being set to an invalid index.
Good afternoon, for me what worked was to create a new xls file, and copy the data from the old to the new one. and the errors stopped.
I am trying to copy a formatted excel sheet from one workbook to another which contains merged cells, font size, font color, font face.
I am able to copy all the sheets from multiple excel workbook to a single workbook but I am unable to get the formatting. Please help
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.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
public class CopyExcelSheets {
public static void main(String args[]) throws IOException {
//Excel sheet names to read from
String [] excelSheets = {"Crystal1.xls","Crystal2.xls","Crystal3.xls","Crystal4.xls","Crystal5Complex.xls"};
//Root folder from where the excel files are read
final String ROOT_FOLDER = "C:\\demo\\shaji\\";
//Output file name for merged excel file (consolidated file)
final String OUTPUT_FILE = "C:\\demo\\shaji\\mergedOutput.xls";
Workbook [] workbook = new Workbook[excelSheets.length];
for(int i = 0; i < excelSheets.length; i++) {
workbook[i] = new HSSFWorkbook(new FileInputStream(ROOT_FOLDER + excelSheets[i]));
}
Workbook newWorkbook = new HSSFWorkbook();
for(int i = 0; i < excelSheets.length; i++) {
newWorkbook = CopyExcelSheets.copy(workbook[i], newWorkbook, "Book-" + i);
}
//Write over to the new file
FileOutputStream fileOut;
fileOut = new FileOutputStream(OUTPUT_FILE);
newWorkbook.write(fileOut);
for(int i = 0; i < excelSheets.length; i++) {
workbook[i].close();
}
newWorkbook.close();
fileOut.close();
}
/*
* Based on the implementation by Faraz Durrani on Stackoveflow
* http://stackoverflow.com/questions/3333021/how-to-copy-one-workbook-sheet-to-another-workbook-sheet-using-apache-poi-and-ja
*/
public static Workbook copy(Workbook oldWorkbook, Workbook newWorkbook, String bookName) throws IOException {
// Need this to copy over styles from old sheet to new sheet. Next step will be processed below
CellStyle newStyle = newWorkbook.createCellStyle();
Row row;
Cell cell;
for (int i = 0; i < oldWorkbook.getNumberOfSheets(); i++) {
HSSFSheet sheetFromOldWorkbook = (HSSFSheet) oldWorkbook.getSheetAt(i);
HSSFSheet sheetForNewWorkbook = (HSSFSheet) newWorkbook.createSheet(bookName + "-" + sheetFromOldWorkbook.getSheetName());
for (int rowIndex = 0; rowIndex < sheetFromOldWorkbook.getPhysicalNumberOfRows(); rowIndex++) {
row = sheetForNewWorkbook.createRow(rowIndex); //create row in this new sheet
for (int colIndex = 0; colIndex < sheetFromOldWorkbook.getRow(rowIndex).getPhysicalNumberOfCells(); colIndex++) {
cell = row.createCell(colIndex); //create cell in this row of this new sheet
//get cell from old/original Workbook's sheet and when cell is null, return it as blank cells.
//And Blank cell will be returned as Blank cells. That will not change.
Cell c = sheetFromOldWorkbook.getRow(rowIndex).getCell(colIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK );
if (c.getCellTypeEnum() == CellType.BLANK){
//System.out.println("This is BLANK " + ((XSSFCell) c).getReference());
}
else {
//Below is where all the copying is happening.
//First it copies the styles of each cell and then it copies the content.
CellStyle origStyle = c.getCellStyle();
newStyle.cloneStyleFrom(origStyle);
cell.setCellStyle(newStyle);
switch (c.getCellTypeEnum()) {
case STRING:
cell.setCellValue(c.getRichStringCellValue().getString());
break;
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
cell.setCellValue(c.getDateCellValue());
} else {
cell.setCellValue(c.getNumericCellValue());
}
break;
case BOOLEAN:
cell.setCellValue(c.getBooleanCellValue());
break;
case FORMULA:
cell.setCellValue(c.getCellFormula());
break;
case BLANK:
cell.setCellValue("");
break;
default:
System.out.println();
}
}
}
}
}
return newWorkbook;
}
}
public Object[][] dataProviderMethod() throws IOException {
try {
file = new FileInputStream(new File("/Users/nanthakumar/Documents/workspace/Myna_Admin/src/com/myna/testdata/login.xls"));
workbook = new HSSFWorkbook(file);
sheet = workbook.getSheetAt(0);
row = sheet.getLastRowNum() + 1;
col = sheet.getRow(0).getLastCellNum();
data = new String[row][col];
for (i = 0; i < row; i++) {
rowvalue = sheet.getRow(i);
for (j = 0; j < col; j++) {
cellValue = rowvalue.getCell(j);
data[i][j] = cellValue.getStringCellValue();
System.out.println("The value is ----->" + data[i][j]);
}
workbook.close();
file.close();
}
} catch (FileNotFoundException nana) {
nana.printStackTrace();
}
return data;
}
This is my code and I tried to add the getnumericalCellvalue() instead of getStringCellValue() but that is not working for me.
first you have to check in the template excel whether the column is number or text.you can get the numerical value if and only if the column is of type number.so change the template excel and try
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?