I've been searching around a lot for this but couldn't find a solution. Hope someone can help me here.
I am using Apache POI to create a simple tool. Formulas will be inputted by user, and the result will be written on file. Im stuck at extending/filling the formula.
Suppose you have a simple excel formula:
IF(A2=B2,True,False)
A drag downwards on excel would result in:
IF(A2=B2,True,False)
IF(A3=B3,True,False)
IF(A4=B4,True,False)
IF(A5=B5,True,False)
. .
.
Now I want to do the same in my program. I will know which row to end. i just can't get the row index to increment. I have already done it manually (writing formula in program), but now I need to use this when formula is passed by user.
I have something like this for the manual part:
for (int ind = 2; ind < rownumb ; ind++)
{
sheet.getRow(i).createCell(12).setCellFormula("IF(K" + ind + "=L" + ind + ",FALSE,TRUE)");
}
Now the user will input:
=IF(K=L, False, True) OR =IF(K0=L0, False, True)
I want to add this formula auto-filling (incrementing) all the way till rownumb. How can I do this?
If there is no direct way, can someone suggest some other approach, however the requirement is that the formula will be passed by user.
Thanks.
Excel does not store it's function "in a sheet's cell" but as a VBA function. In order to be able to properly utilize excel function yourself you will need to emulate that. Check this article about user defined functions, this might get you going.
Related
So I'm having some issues getting Apache POI to evaluate formulas.
Here's the code I call to evaluate formulas before writing:
complete.getCreationHelper().createFormulaEvaluator().evaluateAll();
complete.write(fileOut);
Here's the code I call to write to the cells being used (proving they're numbers):
try{
cell.setCellValue((Double)grid[i][j]);
}
catch(Exception e){
cell.setCellValue((String)grid[i][j]);
}
FYI: grid is a 2D Object array containing only entries of the type double and String.
Here's the formulas I'm trying to evaluate:
"=G13 - H13"
"=STDEV.P(C1:L1)"
"=I13/G13"
Any ideas why when I open up my final workbook in Excel the formulas arn't evaluated? Also, when I click on an unevaluated field and hit enter Excel will recognize the formula and evaluate it. In bulk this isn't practical, but I believe it demonstrates that the cells being used are the correct type. Could this be related to the formulas being of the String type?
EDIT:
OK, so looks like you're supposed to explicitly tell it you have a formula cell. Here's my modified code to do that:
try{
cell.setCellValue((Double)grid[i][j]);
}
catch(Exception e){
String val = (String) grid[i][j];
if (val != null && val.startsWith("=")){
val = val.replaceAll("=", "");
cell.setCellType(XSSFCell.CELL_TYPE_FORMULA);
cell.setCellFormula(val);
}
else{
cell.setCellValue(val);
}
}
Unfortunately you need to remove the equals sign (which is dumb) to pass formulas and then force it to reevaluate before saving (which is dumb). After trying to get it to reevaluate formulas it complained, however, saying:
Caused by:
org.apache.poi.ss.formula.eval.NotImplementedFunctionException:
STDEV.P
I'm imagining that this means Excel has implemented standard deviation calculations but POI hasn't caught up yet?
Try this:
XSSFFormulaEvaluator.evaluateAllFormulaCells(workbook);
or, if you are using xls
HSSFFormulaEvaluator.evaluateAllFormulaCells(hssfWorkbook)
You probably want to call this just before saving.
I'm having a problem where I need to reference the parent cell. So say A1's formula is "=B1", and B1's formula is "=C1". I need to compress A1's formula down to "=C1". I'm not sure if there is a way to do this in excel, or if there is a way to do this Apache POI. I have looked around, but can't really seem to find a solution to this. Does anyone know how to do this in excel or with the POI api?
In your Sample running this would give you the results you asked for.
Sub GetLastPrecedent()
Dim pres As Range
Dim TestCell As Range
Set TestCell = Range("A1")
'Set pres to all cells that are used in getting the value of TestCell
'This includes all precedents of precedents
Set pres = TestCell.Precedents
'This will return the absolute precedent of the ones returned
Set pres = pres.Cells(pres.Rows.Count, pres.Columns.Count)
'This will set the formula in TestCell to use the absolute address
TestCell.Formula = "=" & pres.Address
End Sub
I hope this can at least help guide you to what you are looking for. More info will result in a better answer. Remember if you have complex formula that reference many cells this will become very dangerous and complicated. I only provide this sample based on the information given as a way to help guide you.
Im currently using a program called KNIME, which is used for analysing data. For some of my data, I want each row in a column to be averaged with the value in the previous row. The 'java snippet' option requires a 'global value declaration' and a 'method body'. The column name is 'new acc'.
I understand to use this program more efficiently I'll probably need to learn simple java (and its on my to do), but just for this evening I would like a quick check on some of the data used.
Any help is really appreciated - ive attached an image of the layout.
Thanks!
If you aren't required to use the Java Snippet, I'd recommend the Math Formula node.
There's a Moving Average Node which might be suitable for the task.
What about putting
double acc = Double.NaN;
to the global area, and something like this to the method body:
if (Double.isNaN(acc)) {
acc = $z$;
return $z$;
} else {
double avg = (acc + $z$) / 2;
acc = $z$;
return avg;
}
As a partial answer to the one from Sylvansight, it should be noted that the Java Snippet node is executed on a per row basis, so it's not even possible to use the Java Snippet node to access the values in the previous or subsequent rows.
Math formula node fits better your problem, but if you want to use **java snippet node (simple) ** just put the formula in the return (using normal java sintax). return 1+9;
Task 1: Read each row from one csv file into one seprate txt file.
Task 2: Reverse: in one folder, read text from each txt file and put into a row in a single csv. So, read all txt files into one csv file.
How would you do this? Would Java or Python be good to get this task done in very quickly?
Update:
For Java, there are already some quite useful libraries you can use, for example opencsv or javacsv. But better have a look at wikipedia about csv if no knowledge on csv. And this post tells you all the possibilities in Java.
Note: Due to the simplicity of the question, some one pre-assume this is a homework. I hereby declare it is not.
More background: I am working on my own experiments on machine learning and setting up a large scale test set. I need crawl, scrape and file type transfer as the basic utility for the experiment. Building a lot of things by myself for now, and suddenly want to learn Python due to some recent discoveries and get the feeling Python is more concise than Java for many parsing and file handling situations. Hence got this question.
I just want to save time for both you and me by getting to the gist without stating the not-so-related background. And my questions is more about the second question "Java vs Python". Because I run into few lines of code of Python using some csv library (? not sure, that's why I asked), but just do not know how to use Python. That are all the reasons why I got this question. Thanks.
From what you write there is little need on using something specific for CSV files. In particular for Task 1, this is a pure data I/O operation on text files. In Python for instance:
for i,l in enumerate(open(the_file)):
f = open('new_file_%i.csv' % i, 'w')
f.write(l)
f.close()
For Task 2, if you can guarantee that each file has the same structure (same number of fields per row) it is again a pure data I/O operation:
# glob files
files = glob('file_*.csv')
target = open('combined.csv', 'w')
for f in files:
target.write(open(f).read())
target.write(new_line_speparator_for_your_platform)
target.close()
Whether you do this in Java or Python depends on the availability on the target system and your personal preference only.
In that case I would use python since it is often more concise than Java.
Plus, the CSV files are really easy to handle with Python without installing something. I don't know for Java.
Task 1
It would roughly be this based on an example from the official documentation:
import csv
with open('some.csv', 'r') as f:
reader = csv.reader(f)
rownumber = 0
for row in reader:
g=open("anyfile"+str(rownumber)+".txt","w")
g.write(row)
rownumber = rownumber + 1
g.close()
Task 2
f = open("csvfile.csv","w")
dirList=os.listdir(path)
for fname in dirList:
if fname[-4::] == ".txt":
g = open("fname")
for line in g: f.write(line)
g.close
f.close()
In python,
Task 1:
import csv
with open('file.csv', 'rb') as df:
reader = csv.reader(df)
for rownumber, row in enumerate(reader):
with open(''.join(str(rownumber),'.txt') as f:
f.write(row)
Task 2:
from glob import glob
with open('output.csv', 'wb') as output:
for f in glob('*.txt'):
with open(f) as myFile:
rows = myFile.readlines()
output.write(rows)
You will need to adjust these for your use cases.
I'm using Java and OpenXLS to write out an Excel spreadsheet. I want to set a formula for a cell but I haven't got a clue how to do it. Can anybody help me, please? :)
(Can't tag this with "openxls" because I'm a new user...)
I don't know about OpenXLS, but it's easy to do with Andy Khan's JExcel. I'd recommend trying it. I think it's far superior to POI; I'm betting that it's better than OpenXLS as well.
OpenXLS support very well formulas. Look at this example.
I put a value in the columns A and B of a sheet named "testSheet". In the column C of the same sheet I put the result of SUM (A+B).Don't forget to initialise the column C else you will have a CellNotFoundException
WorkBookHandle workbook = new WorkBookHandle();
workbook.createWorkSheet("testSheet");
WorkSheetHandle sheet = workbook.getWorkSheet("testSheet");
for (int i=1 ;i<=10; i++)
{
sheet.add(10*i, "A"+i);
sheet.add(15*i, "B"+i);
CellHandle cx = sheet.add(0,"C"+i);
cx.setFormula("=SUM(A"+i+":B"+i+")");
}
I hope that that this example will help other people.
Ultimately it turned out that OpenXLS doesn't support formula cells. They are included in the paid for version, though...
You can set the formula String directly on the cell in the Worksheet:
CellHandle cell = ws.add( "=SUM(A1:A3)", "A5" );
This adds the SUM(A1:A3) formula in cell A5. Any Cell set with a String value that is prefixed with '=' is considered a Formula.
Updates and maintenance are now happening on github (search for openxls).