I have a requirement to copy all the individual excel files to one single workbook separated by tabs where I'm using ASPOSE API. But its a paid one.
I have seen another API's which is cell-to-cell copying but its consuming time. I don't find any API to copy directly from the sheet.
Is there any way to copy directly from sheet to sheet?
Here's an example that assumes a directory containing files having the extension .xlsx and each one has a single sheet.
You will need the following imports:
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
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;
And in the example, read the code comments, please:
public static void main(String[] args) {
// provide a path to a folder containing xlsx-workbooks
Path folderWithWorkbooks = Paths.get("Y:\\our\\path\\to\\a\\folder\\with\\workbooks");
// provide a workbook object to be written to
Workbook resultWorkbook = new XSSFWorkbook();
try {
// get the file system objects in that folder
Files.newDirectoryStream(folderWithWorkbooks).forEach(p -> {
// and if one is an xlsx-workbook
if (p.getFileName().toString().endsWith(".xlsx")) {
// try to read its contents
try (FileInputStream fis = new FileInputStream(p
.toAbsolutePath()
.toString())) {
// create the workbook to be parsed
Workbook currentWorkbook = new XSSFWorkbook(fis);
// get the FIRST sheet (adjust code here if you want more sheets)
Sheet sourceSheet = currentWorkbook.getSheetAt(0);
// create a new sheet in the result workbook, name pointing to its origin
Sheet resultSheet = resultWorkbook.createSheet("from "
+ p.getFileName().toString());
// then classicly loop through the rows and cells and copy the contents
for (int r = 0; r < sourceSheet.getPhysicalNumberOfRows(); r++) {
Row sourceRow = sourceSheet.getRow(r);
Row resultRow = resultSheet.createRow(r);
for (int c = 0; c < sourceRow.getPhysicalNumberOfCells(); c++) {
Cell sourceCell = sourceRow.getCell(c);
Cell resultCell = resultRow.createCell(c);
// copy contents with respect to their types
switch (sourceCell.getCellType()) {
case NUMERIC:
resultCell.setCellValue(sourceCell.getNumericCellValue());
break;
case STRING:
resultCell.setCellValue(sourceCell.getStringCellValue());
break;
case FORMULA:
resultCell.setCellValue(sourceCell.getCellFormula());
break;
case BOOLEAN:
resultCell.setCellValue(sourceCell.getBooleanCellValue());
break;
case ERROR:
resultCell.setCellValue(sourceCell.getErrorCellValue());
break;
case BLANK:
case _NONE:
resultCell.setCellValue(sourceCell.getStringCellValue());
break;
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
// write the result workbook to the same folder
FileOutputStream fos = new FileOutputStream(folderWithWorkbooks
.resolve("result.xlsx")
.toAbsolutePath()
.toString());
resultWorkbook.write(fos);
fos.flush();
fos.close();
resultWorkbook.close();
} catch (IOException e) {
e.printStackTrace();
}
}
The result will be a workbook in the same directory with a name result.xlsx.
Please note that this does not copy any cell formatting or styles. You would have to add code for it in the section that copies the cell values.
Related
I am using Apache POI to edit an existing file. This file contains multiple formulas that use the numbers that will be inputted through Apache. And this is where I run into problems, when a number is inputted and that cell is being used in a formula, the file gets corrupted and the formula disappears.
Here the formulas for the 0 are C7+D7, C8+D8, etc.
Here the formulas for the 0 became normal 0, the formulas got lost.
Here is the code I used to write to the excel file:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
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.ss.usermodel.WorkbookFactory;
public class write {
public static void main(String[] args) {
String excelFilePath = "C:\\Users\\jose_\\IdeaProjects\\writeExcel\\src\\JavaBooks.xlsx";
try {
FileInputStream inputStream = new FileInputStream(new File(excelFilePath));
Workbook workbook = WorkbookFactory.create(inputStream);
Sheet sheet = workbook.getSheetAt(0);
/*Cell cell2Update = sheet.getRow(1).getCell(3); // This updates a specific cell: row 0 cell 3
cell2Update.setCellValue(49);*/
Object[][] bookData = {
{2, 17},
{3, 27},
{4, 33},
{5, 44},
};
// int rowCount = sheet.getLastRowNum(); // Gets the last entry
int rowCount = 5;
for (Object[] aBook : bookData) {
Row row = sheet.createRow(++rowCount);
int columnCount = 1;
int lote = 1;
Cell cell = row.createCell(columnCount);
//cell.setCellValue(rowCount); // This sets the index for each entry
cell.setCellValue(lote);
for (Object field : aBook) {
cell = row.createCell(++columnCount);
if (field instanceof String) {
cell.setCellValue((String) field);
} else if (field instanceof Integer) {
cell.setCellValue((Integer) field);
}
}
}
inputStream.close();
FileOutputStream outputStream = new FileOutputStream("C:\\Users\\jose_\\IdeaProjects\\writeExcel\\src\\JavaBooks.xlsx");
workbook.write(outputStream);
workbook.close();
outputStream.close();
} catch (IOException | EncryptedDocumentException ex) {
ex.printStackTrace();
}
}
}
Is there a way to work around this or do I need to set all the formulas again through Apache POI?
You get the error because using code line Row row = sheet.createRow(++rowCount); you always create new empty rows and so you remove all cells in those rows. So you are also removing the cells containing the formulas. Doing so you are damaging the calculation chain. That's what the Excel GUI tells you with the messages.
You should not do this. Instead you always should try to get the rows first using Sheet.getRow. Only if that returns null then you need to create the row.
...
//Row row = sheet.createRow(++rowCount);
Row row = sheet.getRow(rowCount); if (row == null) row = sheet.createRow(rowCount); rowCount++;
...
Additional please read Recalculation of Formulas. So after changing cells referenced in formulas, do always either workbook.getCreationHelper().createFormulaEvaluator().evaluateAll(); or delegate re-calculation to Excel using workbook.setForceFormulaRecalculation(true);.
I am trying to use Apache POI to read an excel file that will have two columns: title and language. Title will have some sentences in a language, language column will be empty. After the Apache POI reads the sentence in the title, it should save it in a variable and then call the language-detect library (https://code.google.com/archive/p/language-detection/). I am especially having an error with the line where there is the case statement
import java.util.ArrayList;
import com.cybozu.labs.langdetect.Detector;
import com.cybozu.labs.langdetect.DetectorFactory;
import com.cybozu.labs.langdetect.Language;
import java.util.Scanner;
import com.cybozu.labs.langdetect.LangDetectException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;
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;
public class LangDetectSample {
public static void main(String[] args) throws IOException, LangDetectException {
String excelFilePath = "C:\\LD\\Books.xlsx";
FileInputStream inputStream = new FileInputStream(new File(excelFilePath));
Workbook workbook = new XSSFWorkbook(inputStream);
Sheet firstSheet = workbook.getSheetAt(0); // Assuming that the data is sheet in one
Iterator<Row> iterator = firstSheet.iterator();
DataFormatter formatter = new DataFormatter();
LangDetectSample lang = new LangDetectSample();
//creating variables
String title;
String language;
int rowNumber;
//Blank workbook
XSSFWorkbook wb = new XSSFWorkbook(); //new workbook //fixed
//Create a blank sheet
Sheet sheet1 = wb.createSheet("Predicted language"); //fixed
while (iterator.hasNext())
{
Row nextRow = iterator.next();
rowNumber = nextRow.getRowNum();
Cell cell = nextRow.getCell(2); // title is in column 2
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
title = cell.getStringCellValue();
break;
case Cell.CELL_TYPE_BOOLEAN:
title = formatter.formatCellValue(cell);
break;
case Cell.CELL_TYPE_NUMERIC:
title = formatter.formatCellValue(cell);
break;
}
System.out.print(title);
//Title should now have the title.
// Call the language detector:
language = lang.detect(title);
System.out.println(lang);
// if language detected, attempt to output the result to the new excel file with the following commands:
// Write the title, language
Row row = sheet1.createRow(rowNumber); //changed var
Cell cell2 = row.createCell(2); //changed variable name
cell.setCellValue(title);
Cell cell3 = row.createCell(3);
cell.setCellValue(language);
}
try {
//Write the workbook in file system
FileOutputStream out = new FileOutputStream(new File("title-language.xlsx"));
workbook.write(out);
out.close();
} catch (Exception e)
{
e.printStackTrace();
}
workbook.close();
inputStream.close();
}
public void init(String profileDirectory) throws LangDetectException {
DetectorFactory.loadProfile(profileDirectory);
}
public String detect(String text) throws LangDetectException {
DetectorFactory.loadProfile("C:\\LD\\profiles");
Detector detector = DetectorFactory.create();
detector.append(text);
return detector.detect();
}
public ArrayList detectLangs(String text) throws LangDetectException {
Detector detector = DetectorFactory.create();
detector.append(text);
return detector.getProbabilities();
}
}
The error I am getting is
variable title may not have been initialised
for your first error of checking boolean, keep the vaiable of "Object" class e.g
Object title;
switch (cell.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN:
title = cell.getBooleanCellValue();
break;
}
for your second error , java reads the cell value default in "double "
data type format , so you need to convert it to text/ String using following method...
Object title="";
title = new DecimalFormat("0").format(Cell.getNumericCellValue());
hope this will help you...
thanks
I think you have problems in cases
now in later version poi 4.0.1 CELL_TYPE_NUMERIC is now just NUMERIC remove CELL_TYPE_
switch (cell.getCellType()) {
case STRING:
title = cell.getStringCellValue();
break;
case BOOLEAN:
title = formatter.formatCellValue(cell);
break;
case NUMERIC:
title = formatter.formatCellValue(cell);
break;
}
This question already has answers here:
how to read exact cell content of excel file in apache POI
(2 answers)
Closed 7 years ago.
I am trying to convert an Excel (.xls) file having multiple worksheets into a .csv. The code works fine but I notice the datatype for certain columns is getting changed from time datatype to double datatype.
Example: If my input is 00:45:20, I am getting output like 0.006168981481481482. Each worksheet has columns using time datatype.
Note: My input do not have date part. Only time component is there. I have seen few posts related to this and tried the same. But the java code is printing only default date and excluded the time part.
I feel something has to be modified in case statement to populate time datatype. I would like to have a generic program so that whenever there is time datatype I have to write it in same format. The code I used:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
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.Row;
public class exceltst
{
static void xls(File inputFile, File outputFile,int sheet_num)
{
// For storing data into CSV files
StringBuffer data = new StringBuffer();
try
{
FileOutputStream fos = new FileOutputStream(outputFile);
// Get the workbook object for XLS file
HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(inputFile));
// Get first sheet from the workbook
HSSFSheet sheet = workbook.getSheetAt(sheet_num);
Cell cell;
Row row;
// Iterate through each rows from first sheet
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext())
{
row = rowIterator.next();
// For each row, iterate through each columns
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext())
{
cell = cellIterator.next();
switch (cell.getCellType())
{
case Cell.CELL_TYPE_BOOLEAN:
data.append(cell.getBooleanCellValue() + ",");
break;
case Cell.CELL_TYPE_NUMERIC:
data.append(cell.getNumericCellValue() + ",");
break;
case Cell.CELL_TYPE_STRING:
data.append(cell.getStringCellValue() + ",");
break;
case Cell.CELL_TYPE_BLANK:
data.append("" + ",");
break;
default:
data.append(cell + ",");
}
}
data.append('\n');
}
fos.write(data.toString().getBytes());
fos.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
File inputFile = new File("C:\\Call_Center_20150323.xls");
File outputFile1 = new File("C:\\live_person.csv");
xls(inputFile, outputFile1,3);
}
}
Could you please help how to populate the time datatype (hh:mm:ss) without date instead of double in the output file?
You should create a CellStyle at the first, then set this style for your time cell. Also for cvs file, you cannot create a CellStyle, you should work on excel file for using cell styles.
For Excel:
CellStyle style = workBook.createCellStyle();
style.setDataFormat(workBook.createDataFormat().getFormat("hh:mm:ss"));
cell.setCellStyle(style);
cell.setCellValue("16:15:11");
For cvs file, you should set value of your Cell as String:
data.append("16:15:11" + ",");
Try
if(cell.getCellType()==Cell.CELL_TYPE_NUMERIC){
if (DateUtil.isCellDateFormatted(cell)) {
System.out.println(cell.getDateCellValue());
} else {
System.out.println(cell.getNumericCellValue());
}
}
For details you can refer here
I've try to run this code in eclipse but I've get this: selection does not contain a main type eclipse.
Does anyone know how I will do it? I am newbie in java and I need help!
The program I try to make is to read excel file using POI! :)
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
public class sample2 {
private void sample2(test)
FileInputStream file = new FileInputStream(new File("C:\\test.xls"));
//Get the workbook instance for XLS file
HSSFWorkbook workbook = new HSSFWorkbook(test);
//Get first sheet from the workbook
HSSFSheet sheet = workbook.getSheetAt(0);
//Get iterator to all the rows in current sheet
Iterator<Row> rowIterator = sheet.iterator();
//Get iterator to all cells of current row
Iterator<Cell> cellIterator = row.cellIterator();
try {
FileInputStream file = new FileInputStream(new File("C:\\test.xls"));
//Get the workbook instance for XLS file
HSSFWorkbook workbook = new HSSFWorkbook(file);
//Get first sheet from the workbook
HSSFSheet sheet = workbook.getSheetAt(0);
//Iterate through each rows from first sheet
Iterator<Row> rowIterator = sheet.iterator();
while(rowIterator.hasNext()) {
Row row = rowIterator.next();
//For each row, iterate through each columns
Iterator<Cell> cellIterator = row.cellIterator();
while(cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch(cell.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN:
System.out.print(cell.getBooleanCellValue() + "\t\t");
break;
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() + "\t\t");
break;
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue() + "\t\t");
break;
}
}
System.out.println("");
}
file.close();
FileOutputStream out =
new FileOutputStream(new File("C:\\test.xls"));
workbook.write(out);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You cannot run a Java application without a main method.
You need something like the following:
public static void main(String[] args) {
sample2 s = new sample2();
s.sample();
}
Also your code contains a lot of errors. You are:
Missing a main method
Capitalization is wrong
Miss types on the input argument for the sample2 method (String test?)
The code is broken many ways. You duplicated the code to read files twice, for error handling, etc.
Reading a good tutorial on Java would help greatly here. A great tutorial on Java and Excel can be found here, and pay some attention to the main method, that's the entry of your Java application.
Your code will not compile due to the identifier "test" in the sample2 method. Remove it and to run the program :
Just add the following method:
public static void main(String[] args) {
new sample2().sample2();
}
I need java code to read data for specific column from excel sheet. – (lo number, line, voucher no, stloc , quantity ,activity.)
These set of values for a particular column will be used for sql query (jdbc-odbc connection done).
The output for the query will be matched with a column in this sheet (this part ll be done later)
Kindly help.
sample excel sheet
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package excelfilereading;
/**
*
* #author vkantiya
*/
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
public class Main {
#SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception {
//
// An excel file name. You can create a file name with a full
// path information.
//
String filename = "FirstExcel.xls";
// Create an ArrayList to store the data read from excel sheet.
//
List sheetData = new ArrayList();
FileInputStream fis = null;
try {
//
// Create a FileInputStream that will be use to read the
// excel file.
//
fis = new FileInputStream(filename);
//
// Create an excel workbook from the file system.
//
HSSFWorkbook workbook = new HSSFWorkbook(fis);
//
// Get the first sheet on the workbook.
//
HSSFSheet sheet = workbook.getSheetAt(0);
//
// When we have a sheet object in hand we can iterator on
// each sheet's rows and on each row's cells. We store the
// data read on an ArrayList so that we can printed the
// content of the excel to the console.
//
Iterator rows = sheet.rowIterator();
while (rows.hasNext()) {
HSSFRow row = (HSSFRow) rows.next();
Iterator cells = row.cellIterator();
List data = new ArrayList();
while (cells.hasNext()) {
HSSFCell cell = (HSSFCell) cells.next();
data.add(cell);
}
sheetData.add(data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
fis.close();
}
}
showExelData(sheetData);
}
private static void showExelData(List sheetData) {
//
// Iterates the data and print it out to the console.
//
for (int i = 0; i < sheetData.size(); i++) {
List list = (List) sheetData.get(i);
for (int j = 0; j < list.size(); j++) {
HSSFCell cell = (HSSFCell) list.get(j);
System.out.print(
cell.getRichStringCellValue().getString());
if (j < list.size() - 1) {
System.out.print(", ");
}
}
System.out.println("");
}
}
}
Have a look at Apache POI - the Java API for Microsoft Documents.
It covers
Excel (SS=HSSF+XSSF)
Word (HWPF+XWPF)
PowerPoint (HSLF+XSLF)
OpenXML4J (OOXML)
OLE2 Filesystem (POIFS)
OLE2 Document Props (HPSF)
Outlook (HSMF)
Visio (HDGF) TNEF (HMEF)
Publisher (HPBF)