My intention is to set the border for the contents of the spreadsheet data while maintaining the other properties of the cell as it is.
The below code formats(setting border) the whole spreadsheet rather than formatting only the portion of spreadsheet where there is actual data.
Is there a reason why the formatting is applied throughout the spreadsheet? And is there a way to overcome this?
package learning.selenium.self.begining;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Iterator;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
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 testing {
public static void main(String[] args) throws Exception {
File myFile = new File("TestFile.xlsx");
Workbook myWorkbook = WorkbookFactory.create(new FileInputStream(myFile));
Sheet mySheet = myWorkbook.getSheetAt(0);
Iterator<Row> r = mySheet.rowIterator();
while (r.hasNext()) {
Row myR = r.next();
Iterator<Cell> c = myR.cellIterator();
while (c.hasNext()) {
Cell myC = c.next();
System.out.println("precessing (" + myR.getRowNum() + "," + myC.getColumnIndex() + ")");
CellStyle s = myC.getCellStyle();
s = myC.getCellStyle();
s.setBorderBottom(BorderStyle.THIN);
s.setBorderTop(BorderStyle.THIN);
s.setBorderLeft(BorderStyle.THIN);
s.setBorderRight(BorderStyle.THIN);
myC.setCellStyle(s);
}
}
FileOutputStream fos = new FileOutputStream(myFile);
myWorkbook.write(fos);
fos.close();
}
}
I dont know if this helps but is worth checking out
CellRangeAddress range= new CellRangeAddress(firstrow, lastrow, firstcol, lastcol);
RegionUtil.setBorderBottom(BorderStyle.THIN, range, sheet);
Same way u can set for other borders.
Related
I've got an XLSX Excel file with a single cell.
When loaded using POI's WorkbookFactory, it's read correctly as a single cell.
When read using POI's XSSFSheetXMLHandler, it's read as though it was two separate cells.
Sheet XML:
<?xml version="1.0" encoding="UTF-8"?>
<x:worksheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<x:sheetData>
<x:row>
<x:c t="inlineStr">
<x:is>
<x:r>
<x:rPr>
<x:rFont val="Segoe UI Emoji"/>
</x:rPr>
<x:t xml:space="preserve">π</x:t>
</x:r>
<x:r>
<x:t xml:space="preserve">more text</x:t>
</x:r>
</x:is>
</x:c>
</x:row>
</x:sheetData>
<x:pageSetup paperSize="9" orientation="portrait" />
</x:worksheet>
Normally you'd expect to see a single item of text per cell, but here it's in two blocks - one formatted using a different font to the other.
Code:
import java.io.File;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.Iterator;
import javax.xml.parsers.SAXParserFactory;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler;
import org.apache.poi.xssf.usermodel.XSSFComment;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
public class MultiTagTest {
public static void main(final String[] args) throws Exception {
final File file = new File("Minimised.xlsx");
try (OPCPackage xlsxPackage = OPCPackage.open(file, PackageAccess.READ)) {
final XSSFReader reader = new XSSFReader(xlsxPackage);
final Iterator<InputStream> iter = reader.getSheetsData();
try (InputStream stream = iter.next()) {
final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setNamespaceAware(true);
final XMLReader sheetParser = saxParserFactory.newSAXParser().getXMLReader();
sheetParser.setContentHandler(new XSSFSheetXMLHandler(reader.getStylesTable(),
new ReadOnlySharedStringsTable(xlsxPackage), new SheetContentsHandler() {
#Override
public void startRow(final int rowNum) {
}
#Override
public void endRow(final int rowNum) {
}
#Override
public void cell(final String cellReference, final String formattedValue,
final XSSFComment comment) {
System.out.println(MessageFormat.format(
"XSSFSheetXMLHandler Cell - cellReference={0}, formattedValue={1}, comment={2}",
cellReference, formattedValue, comment));
}
}, true));
sheetParser.parse(new InputSource(stream));
}
}
try (Workbook workbook = WorkbookFactory.create(file, null, true)) {
final Row row = workbook.getSheetAt(0).getRow(0);
for (int col = row.getFirstCellNum(); col < row.getLastCellNum(); col++) {
System.out.println(MessageFormat.format("WorkbookFactory Cell - {0}", row.getCell(col)));
}
}
}
}
Output:
XSSFSheetXMLHandler Cell - cellReference=null, formattedValue=π, comment=null
XSSFSheetXMLHandler Cell - cellReference=null, formattedValue=more text, comment=null
WorkbookFactory Cell - πmore text
From inside the SheetContentsHandler's cell method, it's not possible to tell that they were the same cell.
My Requirement is to read data from input excel file and write it in output excel file I am using JAVA 8 AND APACHE POI
During the write process I am changing the date format for a particular column from mm/dd/yyyy to dd/mm/yyyy
With below code its setting current date in excel, I want to set same values of input excel in output excel but with new format defined.
Any help would be really appreciated
Below is Updated code:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
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;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFCreationHelper;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
class DateFormatDemo1{
public static void main( String[] args ) throws IOException, InvalidFormatException, ParseException
{
OPCPackage pkg = OPCPackage.open(new File("C:\\DateFormatIssue\\SourceFile\\S.xlsx"));
XSSFWorkbook wb = new XSSFWorkbook(pkg);
XSSFCreationHelper createHelper = wb.getCreationHelper();
XSSFSheet sheet = wb.getSheetAt(0); // Create spreadsheet in workbook
Iterator<Row> iterator = sheet.iterator();
Cell cell = null;
Row row=null;
row=iterator.next();
int pos=11;
while(iterator.hasNext())
{
row=iterator.next();
cell= row.getCell(pos-1);
XSSFCellStyle cellStyle = (XSSFCellStyle)cell.getCellStyle();
cellStyle.setDataFormat( createHelper.createDataFormat().getFormat("M/dd/yyyy")); // set the format of the date
SimpleDateFormat sdf = new SimpleDateFormat("d/M/yyyy");
Date d=null;
/** below if block converts dates which are in format d/M/yyyy (15/04/2017) to M/d/yyyy (4/15/2017)**/
if (cell.getCellType() == Cell.CELL_TYPE_STRING)
{
d= sdf.parse(cell.getStringCellValue());
cell.setCellValue(d);
cell.setCellStyle(cellStyle);
}
else if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC)
{
cell.setCellValue(cell.getNumericCellValue());
}
}
FileOutputStream outFile =new FileOutputStream(new File("C:\\DateFormatIssue\\OutputFile\\output.xlsx"));
wb.write(outFile);
wb.close();
outFile.close();
pkg.close();
}}
import java.io.File;
import java.io.IOException;
import jxl.*;
import jxl.write.*;
import jxl.write.Number.*;
import jxl.Cell;
import jxl.CellType;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
public class reader {
public static void main(String args[]) throws IOException, WriteException, BiffException {
String inputFile = "C:\\Users\\Chemeris\\Documents\\Book1.xls";
File inputWorkbook = new File(inputFile);
Workbook w = Workbook.getWorkbook(inputWorkbook);
Sheet sheet = w.getSheet(0);
//Ading a label
Label label = new Label(2,2, "Hello");
sheet.addCell(label);
w.write();
w.close();
}
}
I get a cannot find symbol error on ".addCell" and on ".write".
If you can help me solve this problem or offer another solution to wrting to an existing excel file I would be most thankfull
You may try to use ApachePOI to get the same result. There are bunch of documents https://www.tutorialspoint.com/apache_poi/)
I'm working with apache poi, i read some xlsx file, process it and then export them in xlsx format as well. But now i have the requirement of the export format to be XLS (this is to support old devices). Is there an easy way of convert the code-generated xlsx file to xls?
The all process is made with XSSF implementation.
Thanks in advance.
I agree with centic answer, but I want to add a few lines of code.
You said that you are using XSSF implementation.
So, for the workbook that you are saving do the following changes:
change XSSFWorkbook x = new XSSFWorkbook();
to Workbook x = new HSSFWorkbook();
where Workbook is import from org.apache.poi.ss.usermodel.Workbook;
Similarly
Change XSSFRow instantiation from
XSSFRow r = newXSSF();
to Row r = new HSSFRow();
and import the Row from org.apache.poi.ss.usermodel.Row;
Like the same way, change Cell instantiation to ss.usermodel package.
And finally save your HSSF workbook with .xls extension.
You will need to switch to the "ss" implementation which allows to transparently work with both HSSF (=XLS) and XSSF (=XSLX), see http://poi.apache.org/spreadsheet/converting.html for some details of the original HSSF -> SS switch which should also shed some light on supporting it for the other way around.
Then only the two constructors for HSSFWorkbook/XSSFWorkbook are needed to decide which of the two formats you want to produce.
I have faced same scenario and implemented below code for Coverting XLSX to XLS using Java
Below code will read it from directory and process using apache camel (polling file from path) and apace poi
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Optional;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
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.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
#Component
public class ExcelFileProcessor implements Processor {
final Logger logger = LoggerFactory.getLogger(getClass());
#Value("${test.dir.in}")
private String inDir;
#Override
public void process(Exchange exchange) throws Exception {
logger.info("Entry-ExcelFileProcessor- Process method");
long start = System.currentTimeMillis();
String fileNameWithExtn=(String) exchange.getIn().getHeader("camelFileName");
Long originalFileSize = (Long) exchange.getIn().getHeader("CamelFileLength");
String fileNameWithOutExtn = fileNameWithOutExtn(fileNameWithExtn);
logger.info("fileNameWithExtn:{}" ,fileNameWithExtn);
logger.info("fileNameWithOutExtn:{}" ,fileNameWithOutExtn);
logger.info("originalFileSize:{}" ,originalFileSize);
try(InputStream in = exchange.getIn().getBody(InputStream.class);
XSSFWorkbook wbIn = new XSSFWorkbook(in);
Workbook wbOut = new HSSFWorkbook();) {
int sheetCnt = wbIn.getNumberOfSheets();
for (int i = 0; i < sheetCnt; i++) {
Sheet sIn = wbIn.getSheetAt(0);
Sheet sOut = wbOut.createSheet(sIn.getSheetName());
Iterator<Row> rowIt = sIn.rowIterator();
while (rowIt.hasNext()) {
Row rowIn = rowIt.next();
Row rowOut = sOut.createRow(rowIn.getRowNum());
Iterator<Cell> cellIt = rowIn.cellIterator();
while (cellIt.hasNext()) {
Cell cellIn = cellIt.next();
Cell cellOut = rowOut.createCell(cellIn.getColumnIndex(), cellIn.getCellType());
switch (cellIn.getCellType()) {
case Cell.CELL_TYPE_BLANK: break;
case Cell.CELL_TYPE_BOOLEAN:
cellOut.setCellValue(cellIn.getBooleanCellValue());
break;
case Cell.CELL_TYPE_ERROR:
cellOut.setCellValue(cellIn.getErrorCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
cellOut.setCellFormula(cellIn.getCellFormula());
break;
case Cell.CELL_TYPE_NUMERIC:
cellOut.setCellValue(cellIn.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING:
cellOut.setCellValue(cellIn.getStringCellValue());
break;
}
CellStyle styleIn = cellIn.getCellStyle();
CellStyle styleOut = cellOut.getCellStyle();
styleOut.setDataFormat(styleIn.getDataFormat());
cellOut.setCellComment(cellIn.getCellComment());
}
}
}
File outF = new File(inDir+fileNameWithOutExtn+".xls");
try(OutputStream out = new BufferedOutputStream(new FileOutputStream(outF));){
wbOut.write(out);
}
}catch (Exception e) {
logger.info("Error during Excel file process:{}",e.getMessage());
}
long end = System.currentTimeMillis();
logger.info("Total time processed for file in - {} ms", (end - start));
logger.info("Exit-FileProcessor- Process method");
}
public String fileNameWithOutExtn(String fileName) {
return Optional.of(fileName.lastIndexOf('.')).filter(i-> i >= 0)
.map(i-> fileName.substring(0, i)).orElse(fileName);
}
}
If you are not using camel and want to get inputstream from file use below snippet
String inpFn = "input.xlsx";
String outFn = "output.xls";
InputStream in = new BufferedInputStream(new FileInputStream(inpFn));
try {
Workbook wbIn = new XSSFWorkbook(in);
File outF = new File(outFn);
if (outF.exists())
outF.delete();
Workbook wbOut = new HSSFWorkbook();
//continue with above code
I'm trying to export some data into Excel files. For which I'm using POI.
As I understand Cell.setCellType(double) sets the appropriate excel equivalent numeric value. But this doesn't change type of the cell.
Column type when I open the generated excel file is General in the Home tab.
Following is a sample code to test it.
package com.example;
import java.io.FileOutputStream;
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 TestExcelMain {
public static void main(String[] args) throws Exception {
System.out.println("started");
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue(3.14159);
workbook.write(new FileOutputStream("Test.xlsx"));
System.out.println("finished");
}
}
Is there any other way available to set the cell type to appropriate type ?
I have also tried Cell.setCellType(Cell.CELL_TYPE_NUMERIC) with exactly same result.
Correct type of cell that I expect is Number.
I also tried using all XSSF classess (code below) as suggested in this post setCellType(HSSFCELL.CELL_TYPE_NUMERIC) is not working in apache poi
package com.example;
import java.io.FileOutputStream;
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 TestExcelMain {
public static void main(String[] args) throws Exception {
System.out.println("started");
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet();
XSSFRow row = sheet.createRow(0);
XSSFCell cell = row.createCell(0);
cell.setCellValue(3.14159);
cell.setCellType(XSSFCell.CELL_TYPE_NUMERIC);
workbook.write(new FileOutputStream("Test.xlsx"));
System.out.println("finished");
}
}
Edit
As answered by Jim Garrison, setting cell style does change the type to number. Following is working code.
package com.example;
import java.io.FileOutputStream;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFDataFormat;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class TestExcelMain {
public static void main(String[] args) throws Exception {
System.out.println("started");
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet();
XSSFRow row = sheet.createRow(0);
XSSFCell cell = row.createCell(0);
cell.setCellValue(3.14159);
cell.setCellType(XSSFCell.CELL_TYPE_NUMERIC);
XSSFDataFormat format = workbook.createDataFormat();
XSSFCellStyle style = workbook.createCellStyle();
style.setDataFormat(format.getFormat("0.0"));
cell.setCellStyle(style);
workbook.write(new FileOutputStream("Test.xlsx"));
System.out.println("finished");
}
}
From the Javadoc for setCellValue(double value) (emphasis mine):
value - the numeric value to set this cell to. For formulas we'll set the precalculated value, for numerics we'll set its value. For other types we will change the cell to a numeric cell and set its value.
So no matter what the cell was before, this method changes the cell type to numeric anyway.
Note that "General" has nothing to do with the cell type, and everything to do with the cell format. To change the way a cell displays, use setCellStyle().