I have searched through StackOverflow, but didn't find a clear answer to my question.
I have a simple 2 columns and 24 rows xlsx (excel) file (later on this file will have more columns and rows , and also eventually it will have different sheets).
First row is header row: year=x and population=y, and for each header I want to read the rows below. Later on I want to be able to use this information to create a dynamic plot (x,y),
So I think I need to save the x and y information in variables. Below is my pseudo code.
//Sheet Pop
final String POP = "Pop";
int startRowHeader = 1,
startRowNumeric = 2,
startColNumeric = 1,
nrOfCols = 0,
nrOfRows = 0;
int nrOfSheets = excelFile.getWorkbook().getNumberOfSheets();
org.apache.poi.ss.usermodel.Sheet sheet1 = excelFile.getWorkbook().getSheetAt(0);
String[] sheets = {POP};
boolean sheetExists;
String activeSheet = "";
nrOfCols = sheet1.getRow(0).getLastCellNum();
nrOfRows = excelFile.getLastRowNum(POP);
try {
for (String sheet : sheets) {
sheetExists = false;
for (int sheetIndex = 0; sheetIndex < nrOfSheets; sheetIndex++) {
if (sheet.equalsIgnoreCase( excelFile.getWorkbook().getSheetName(sheetIndex))) {
SheetExists = true;
}
}
if (!sheetExists) {
throw new Exception("Sheet " + sheet + " is missing!");
}
}
//Take off!
// Sheet Pop
activeSheet = sheets[0];
for(int j=0; j < nrOfCols; j++) {
for(int i=0; i<nrofRows; i++) {
column[i] = (int)excelFile.getCellNumericValue(POP, startRowNumeric, startColNumeric);
}
}
} catch (Exception e) {
traceln(" ..... ");
traceln("Error in sheet: " + activeSheet);
traceln("Message: " + e.getMessage()); //Write out in console
}
create a new class:
public class Point {
int x;
int y;
}
in your main function create a
List<Point> allPoints = new List<Point>();
then add the points you read from excel to this List
do this in a loop
Point p = new Point();
p.x = xCoordinateFromExcel;
p.y = yCoordinateFromExcel;
allPoints.add(p);
also consider adding constructor and getter/setters to your Point class.
also you might want to use the Point class available in java.awt directly.
http://docs.oracle.com/javase/7/docs/api/java/awt/Point.html
EDIT: regarding fetching values from excel
this is what i understand from your question
you have 24 rows with 2 columns
first column has x, second column has y value
so you can just do something like this in a loop
for(int i=0;i<24;i++){
Row row = sheet.getRow(i);
Cell cellX = row.getCell(1);
Cell cellY = row.getCell(2);
//assign to point class
...
}
dont forget to parse it to int, or use getNumericCellValue()
http://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/Cell.html#getNumericCellValue()
You can use a java.util.ArrayList of java.awt.geom.Point2D.Double
Declare the list:
ArrayList<Point2D.Double> points = new ArrayList<>();
Then for each row:
// Read x
// Read y
Point2D.Double p = new Point2D.Double(x, y);
/// And add to the list:
points.add(p);
Related
I was trying to read data from an excel sheet that contains empty cells consider the following code:
File src = new File(path to your file);
FileInputStream fis = new FileInputStream(src);
XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet sheet1 = wb.getSheet("Sheet1");
int rowCount = sheet1.getLastRowNum();
System.out.println("total number of rows is: " + rowCount);
for(int i = 1; i < rowCount; i++) {
//getcell returns row num and starts from 1
//Also my sheet column contains data in numeric form
int data = (int) sheet1.getRow(i).getCell(1).getNumericCellValue();
System.out.println(data);
}
However, my code also reads the empty cells and displays the value as 0 (The cells have numeric value). How do I make my script read-only cells that are filled and display them while ignoring the ones that are empty?
Thank you in advance
Just update the for loop with an if condition which will check for the value which is getting retrieved from the Cell. PFB the updated for loop.
For Apache POI version 4.x you can try below-
for(int i = 1; i < rowCount; i++) {
//getcell returns row num and starts from 1
//Also my sheet column contains data in numeric form
Cell cell = sheet1.getRow(i).getCell(1);
int data = (int) sheet1.getRow(i).getCell(1).getNumericCellValue();
if(c.getCellType() == CellType.Blank)
{
continue;
}
else{
System.out.println(data);
}
}
For Apache POI version 3.x you can try below-
for(int i = 1; i < rowCount; i++) {
//getcell returns row num and starts from 1
//Also my sheet column contains data in numeric form
Cell cell = sheet1.getRow(i).getCell(1);
int data = (int) sheet1.getRow(i).getCell(1).getNumericCellValue();
if(cell.getCellType() == Cell.CELL_TYPE_BLANK)
{
continue;
}
else{
System.out.println(data);
}
}
Currently, this program will run down a column of URLs and output the selected data to the neighboring cell. I can set which column it starts on, but that is all I can do. Right now, I only have it working on one column. How can I instruct it to go to say, column 4 (Column E) and work top down once it is through with column 0 (A)? And then perhaps another, say column J after that?
I believe my problem lies within the "while (!(cell = sheet.getCell..." line, but I am unsure of what to change there without breaking the program.
My code is as follows:
public class App {
private static final int URL_COLUMN = 0; // Column A
private static final int PRICE_COLUMN = 1; //Column B
public static void main(final String[] args) throws Exception {
Workbook originalWorkbook = Workbook.getWorkbook(new File("C:/Users/Shadow/Desktop/original.xls"));
WritableWorkbook workbook = Workbook.createWorkbook(new File("C:/Users/Shadow/Desktop/updated.xls"), originalWorkbook);
originalWorkbook.close();
WritableSheet sheet = workbook.getSheet(0);
int currentRow = 1;
Cell cell;
while (!(cell = sheet.getCell(URL_COLUMN, currentRow)).getType().equals(CellType.EMPTY)) {
String url = cell.getContents();
System.out.println("Checking URL: " + url);
if (url.contains("scrapingsite1.com")) {
String Price = ScrapingSite1(url);
System.out.println("Scraping Site1's Price: " + Price);
Label cellWithPrice = new Label(PRICE_COLUMN, currentRow, Price);
sheet.addCell(cellWithPrice);
}
currentRow++;
}
workbook.write();
workbook.close();
}
private static String ScrapingSite1 (String url) throws IOException {
Document doc = null;
for (int i=1; i <= 6; i++) {
try {
doc = Jsoup.connect(url).userAgent("Mozilla/5.0").timeout(6000).validateTLSCertificates(false).get();
break;
} catch (IOException e) {
System.out.println("Jsoup issue occurred " + i + " time(s).");
}
}
if (doc == null){
return null;
}
else{
return doc.select("p.price").text();
}
}
}
To simplify the code I made an assumption that the price comes always to the next column (+1).
Also to process few columns instead of using single value int URL_COLUMN = 0 I replaced it with array of columns to process: int[] URL_COLUMNS = { 0, 4, 9 }; // Columns A, E, J.
You can then loop over every column {0, 4, 9} and save the data to the next column {1, 5, 10}.
private static final int[] URL_COLUMNS = { 0, 4, 9 }; // Columns A, E, J
public static void main(final String[] args) throws Exception {
Workbook originalWorkbook = Workbook.getWorkbook(new File("C:/Users/Shadow/Desktop/original.xls"));
WritableWorkbook workbook = Workbook.createWorkbook(new File("C:/Users/Shadow/Desktop/updated.xls"), originalWorkbook);
originalWorkbook.close();
WritableSheet sheet = workbook.getSheet(0);
Cell cell;
// loop over every column
for (int i = 0; i < URL_COLUMNS.length; i++) {
int currentRow = 1;
while (!(cell = sheet.getCell(URL_COLUMNS[i], currentRow)).getType().equals(CellType.EMPTY)) {
String url = cell.getContents();
System.out.println("Checking URL: " + url);
if (url.contains("scrapingsite1.com")) {
String Price = ScrapingSite1(url);
System.out.println("Scraping Site1's Price: " + Price);
// save price into the next column
Label cellWithPrice = new Label(URL_COLUMNS[i] + 1, currentRow, Price);
sheet.addCell(cellWithPrice);
}
currentRow++;
}
}
workbook.write();
workbook.close();
}
I have a java application that exports some data to a spreadsheet using POI. The problem is that sometimes (not always) there are a couple of lines that have no information (they are "blank") but when I save the XLS document to my desktop and open it, the cells are filled with the correct information.
Im using POI 3.7.
Down here you have an example of what's happening.
[EDIT] - I add some code:
This is the method that insert the data into the sheet:
public void setTransactionDetailsData(HSSFSheet sheet, String[][] records){
HSSFRow rowContent = null;
HSSFCell cellContent = null;
String cell = "";
Integer recordNumber = records.length;
Integer columnNumber = records[0].length;
Integer nextDataIndex = 0;
String styleText = "";
boolean customStyles = styles.size()>0;
short alignment;
CellStyle cellStyle = null;
for(int i = 0; i<recordNumber;i++){
//New row
rowContent = sheet.createRow(lastRowCreated);
rowContent.setHeightInPoints((customDataCellHeight * sheet.getDefaultRowHeightInPoints()));
for(int j = 0; j<columnNumber;j++){
cellContent = null;
cellContent = rowContent.createCell((nextDataIndex));
cell = records[i][j];
if(customStyles){
try{
styleText = styles.get(nextDataIndex);
alignment = getAlignment(styleText);
}catch(IndexOutOfBoundsException e){
LOG.info("Error while obtaining style for position " +nextDataIndex+ ", max index is " +(styles.size()-1)+ ". Check the list of styles you send");
styleText = "";
alignment = 1;
}
}else{
alignment = 1;
}
cellStyle = getCellStyle(i,Integer.valueOf(alignment),styleText);
//Text
if("".equals(styleText) || "value_left".equals(styleText) || "value".equalsIgnoreCase(styleText)){
cellContent.setCellValue(cell);
}else{
if(isNumeric(cell)){
try{
cellContent.setCellValue(convertoToParseableNumber(cell));
cellContent.setCellType(0);
}catch(NumberFormatException e){
LOG.info("Error ocurred while parsing value " +cell+ " no number");
cellContent.setCellValue(cell);
}
}else{
cellContent.setCellValue(cell);
}
}
cellContent.setCellStyle(cellStyle);
nextDataIndex++;
}
//Back to first column
nextDataIndex = 0;
lastRowCreated++;
}
autosize(sheet);
}
Thank you in advance.
I have an Excel worksheet with some Text cells that contains a superscript and an hyperlink. The hyperlink is simple to extract but i could't extract the superscript :/, the program detects it like plain text. "8^2 --> 82".
The code
excel = WorkbookFactory.create(new File("filename.xlsx"));
Sheet hoja = excel.getSheetAt(4);
List<String> datos = new ArrayList<String>();
List<String> links = new ArrayList<String>();
//recorrido
Iterator<Row> filas = hoja.rowIterator();
while (filas.hasNext()) {
Row fila = filas.next();
Iterator<Cell> celdas = fila.cellIterator();
while (celdas.hasNext()) {
Cell celda = celdas.next();
System.out.print(celda.toString() + " || ");
datos.add(String.valueOf(celda));
Hyperlink linkAddress = celda.getHyperlink();
if (linkAddress != null) {
links.add(linkAddress.getAddress());
}
}
System.out.println();
}
The code shows how i'm whatching the cell contain, just the code probe.
I'm using Apache POI 3.14.
I solved this problem using some RichTextString properties. I created two methods to extract the value and the superscript of the Cell's RichTextString.
To obtain the value we may need to iterate and to concatenate all the String content, except the last one. The last one is always the full superscript.
private static String getValue(XSSFRichTextString cellContent){
String value = "";
for (int i = 0; i < cellContent.numFormattingRuns() - 1; i++) {
int lenVal = cellContent.getLengthOfFormattingRun(i);
int iVal = cellContent.getIndexOfFormattingRun(i);
value += cellContent.toString().substring(iVal, lenVal + iVal);
}
return value;
}
private static String getSuperScript(XSSFRichTextString cellContent) {
int lenSuper = cellContent.getLengthOfFormattingRun(cellContent.numFormattingRuns() - 1);
int iSuper = cellContent.getIndexOfFormattingRun(cellContent.numFormattingRuns() - 1);
return cellContent.toString().substring(iSuper, lenSuper + iSuper);
}
It obtains from 8^1 --> value=8, superScript=1 for example.
Or from "superscript example ^ A,B" --> value="superscript example", superScript="A,B".
I am trying to show ComboBox in JXL API with following Code:
ArrayList<String> arrList = new ArrayList<String>();
arrList.add("DropDown1");
arrList.add("DropDown2");
arrList.add("DropDown3");
WritableCellFeatures cellFeatures = new WritableCellFeatures();
cellFeatures.setDataValidationList(arrList);
Blank b = null;
Label checkLabel = null;
for (int x = 0; x < xlData.size(); x++) {
for (int i = 0; i <= 14; i++) {
System.out.println("X:" + x + "I:" + i);
if (i > 9) {
checkLabel = new Label(i, x + xlHeader.size(),(String) arrList.get(0));
//b = new Blank(i, x + xlHeader.size());
//b.setCellFeatures(cellFeatures);
checkLabel.setCellFeatures(cellFeatures);
writableSheet.addCell(checkLabel);
System.out.println("Combo Cell : " + x + ":" + i);
}
}
}
I have tried both "Blank" Cell as well as "Label". But still the Excel is not showing ComboBox.
If you call close() without calling write() first, a completely empty file will be generated.
Once you have finished adding sheets and cells to the workbook, you call write() on the workbook, and then close the file. This final step generates the output file (output.xls in this case) which may be read by Excel. credits this excellent tutorial it's required to add:
copy.write();
copy.close();
The cellFeatures needs to be re-instantiate inside the loop
according to my tests this code works fine:
WritableCellFeatures cellFeatures = null;
Label checkLabel = null;
for (int x = 0; x < xlData.size(); x++) {
for (int i = 0; i <= 14; i++) {
System.out.println("X:" + x + "I:" + i);
if (i > 9) {
checkLabel = new Label(i, x + xlHeader.size(), (String) arrList.get(0));
cellFeatures = new WritableCellFeatures();
cellFeatures.setDataValidationList(arrList);
checkLabel.setCellFeatures(cellFeatures);
writableSheet.addCell(checkLabel);
}
}
}
// All cells modified/added. Now write out the workbook
workbook.write();
workbook.close();
Even the Blank version works but in this case the cell hasn't an initial value
according to my tests also this code works fine:
WritableCellFeatures cellFeatures = null;
Blank b = null;
for (int x = 0; x < xlData.size(); x++) {
for (int i = 0; i <= 14; i++) {
System.out.println("X:" + x + "I:" + i);
if (i > 9) {
b = new Blank(i, x + xlHeader.size());
cellFeatures = new WritableCellFeatures();
cellFeatures.setDataValidationList(arrList);
b.setCellFeatures(cellFeatures);
writableSheet.addCell(b);
}
}
}
// All cells modified/added. Now write out the workbook
workbook.write();
workbook.close();
If you open the generated file .xls with Excel 2010 or Excel 2013 you may need to save as .xlsx to see the combo.
I experienced that opening .xls by Excel2010/2013,
even if the cells actually contains a data validation list and the validation constraints works the data validation arrow are missing; that you need to save as in the new format if you want see the arrow and the combobox.
Moreover this drawback seems rather caused by the last Excel versions and not by JXL, demonstrated by the fact that opening the .xls in OpenOffice.org Cal 3.4.1 there is not any problem and the combo works correctly; this could be related to the fact that the current version jxl 2.6.12
2009-10-26 I use for the test Generates spreadsheets in Excel 2000 format
The Java code developed for this answer is available to anyone who wants to improve or fork and play with it.