I'm new to Groovy, and coming from PHP it's been a rough transition.
The code below works. However, I would appreciate feedback on how better to write it and follow good practice with Groovy.
I anticipate doing a lot of Excel work in the future, and so tried to make this program reusable for more than just FizzBuzz.
/*
* In Excel: Create a workbook with a blank sheet, "output"
* and a sheet "input" with the values
* startValue : 0
* endValue : 100
* fizz : 3
* buzz : 5
*
* In Groovy: Create a program that will
* - Open an Excel file
* - Extract the four parameters above
* - Run a "FizzBuzz" on those parameters
* - Write the results to the "output" sheet
*
* FizzBuzz: For all values in a range
* If the value is divisible by 3, print "fizz"
* If the value is divisible by 5, print "buzz"
* If the value is divisible by 3 and 5, print "fizzbuzz"
* Otherwise print the value
*
* The program below uses Apache POI to parse Excel.
*/
package org.example
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
import org.apache.poi.ss.usermodel.*
import org.apache.poi.xssf.usermodel.*
class Excel {
def file;
def workbook;
static main(def args) throws Exception {
new Excel()
}
Excel(){
file = new FileInputStream("input.xlsx")
workbook = WorkbookFactory.create(file)
def sheetIn = workbook.getSheet("input")
def fizzbuzz = new Excel.FizzBuzz()
def params = fizzbuzz.setFromSheet(sheetIn)
def sheetOut = workbook.getSheet("output")
this.doByRow(sheetOut, params.start, params.end, { rowNum, value ->
def row = row(sheetOut, rowNum)
setCell(row, 0, value)
setCell(row, 1, fizzbuzz.calculate(value))
})
def fileOut = new FileOutputStream(filename("fizzbuzz"))
workbook.write(fileOut)
}
def filename(value){
return "out/" + value + "_" + System.currentTimeMillis() + ".xlsx"
}
def doByRow(sheet,startValue,endValue,doSomething){
def rowNum = 0;
for(
def value = startValue;
value <=endValue;
value = value + 1
){
doSomething(rowNum, value)
rowNum = rowNum + 1
}
}
def hlookup(sheet, value, toTheRight){
for(row in sheet){
for(int index = 0; index < row.getLastCellNum(); index++){
def cellValue = getCellValue(row, index)
if(cellValue == value){
return getCellValue(row, index + toTheRight)
}
}
}
}
def row(sheet,index){
def rowOut = sheet.getRow(index)
if(rowOut == null) rowOut = sheet.createRow(index)
return rowOut
}
def getCellValue(row,index){
def cellOut = row.getCell(index)
def output
switch (cellOut.getCellType()){
case 0: /*Cell type numeric*/
output = cellOut.getNumericCellValue()
if(output % 1 == 0) output = output.toInteger()
else output = output.toFloat()
break
case null:
row.createCell(index).setCellType("string")
output = ""
break
default:
output = cellOut.getStringCellValue().toString()
break
}
return output
}
def setCell(row, index, value){
def cellOut = row.getCell(index)
if(cellOut == null){
cellOut = row.createCell(index)
}
cellOut.setCellValue(value)
}
class FizzBuzz{
def params = [
"start" :0,
"end" :0,
"fizz" :0,
"buzz" :0
]
def setFromSheet(sheet){
this.params.start = Excel.this.hlookup(sheet,"startValue",1)
this.params.end = Excel.this.hlookup(sheet,"endValue",1)
this.params.fizz = Excel.this.hlookup(sheet,"fizz",1)
this.params.buzz = Excel.this.hlookup(sheet,"buzz",1)
return this.params;
}
def calculate(num){
def output = ""
if(num % this.params.fizz.toFloat() == 0) output += "fizz"
if(num % this.params.buzz.toFloat() == 0) output += "buzz"
if(output == "") output = num;
return output;
}
}
}