diff --git a/build.gradle b/build.gradle index ebc7b13..c7f57b2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,22 +1,34 @@ +buildscript { + repositories { + maven { url "https://repo.grails.org/grails/core" } + mavenCentral() + } + dependencies { // Not Published to Gradle Plugin Portal + classpath "org.grails:grails-gradle-plugin:6.2.4" + } +} + plugins { id "groovy" id "java-library" id "war" id "idea" - id "org.grails.grails-plugin" - id "org.grails.internal.grails-plugin-publish" id "application" id "eclipse" + id "maven-publish" } -group "org.grails.plugins" +// Not Published to Gradle Plugin Portal +apply plugin: "org.grails.grails-plugin" -sourceCompatibility = 1.8 -targetCompatibility = 1.8 +group "org.grails.plugins" repositories { mavenCentral() - maven { url "https://repo.grails.org/grails/core" } + maven { + name "Grails" + url "https://repo.grails.org/grails/core" + } } dependencyManagement { @@ -35,18 +47,23 @@ dependencies { implementation "org.grails:grails-web-boot" implementation "org.grails:grails-dependencies" - api 'net.sf.opencsv:opencsv:2.3' + api 'com.opencsv:opencsv:5.10' - api 'com.lowagie:itext:2.1.7' - api "com.lowagie:itext-rtf:2.1.7" + api 'com.github.librepdf:openpdf:1.4.2' + api 'com.github.librepdf:openrtf:1.2.1' runtimeOnly 'xerces:xercesImpl:2.12.2' - api 'org.odftoolkit:simple-odf:0.6.6' - api 'net.sourceforge.jexcelapi:jxl:2.6.12' - api 'commons-beanutils:commons-beanutils:1.9.4' - api 'commons-codec:commons-codec:1.17.0' + api 'org.odftoolkit:simple-odf:0.9.0' + api 'org.apache.poi:poi:5.4.0' + api 'org.apache.poi:poi-ooxml:5.4.0' - testCompileOnly "org.grails:grails-plugin-testing" + api 'commons-beanutils:commons-beanutils:1.10.1' + api 'commons-codec:commons-codec:1.18.0' +} + +java { + sourceCompatibility = JavaVersion.toVersion("11") + targetCompatibility = JavaVersion.toVersion("11") } jar { @@ -64,24 +81,94 @@ jar { archiveClassifier='' } -grailsPublish { - license { - name = 'Apache-2.0' - } +publishing { + publications { + maven(MavenPublication) { + pom { + name = "Grails Export Plugin" + description = "This plugin offers export functionality supporting different formats e.g. CSV, Excel, Open Document Spreadsheet, PDF and XML and can be extended to add additional formats." - title = "Grails Export Plugin" - desc = "This plugin offers export functionality supporting different formats e.g. CSV, Excel, Open Document Spreadsheet, PDF and XML and can be extended to add additional formats." - - developers = [ graemerocher: 'Graeme Rocher', - puneetbehl: 'Puneet Behl', - nwwells: 'Nathan Wells', - tulu: 'Ruben', - arturoojeda: 'Arturo Ojeda López', - fabiooshiro: 'Fabio Issamu Oshiro', - ddelponte: 'Dean Del Ponte', - cristallo: 'Cristiano Limiti', - mirweb: 'Mirko Weber', - joasgarcia: 'Joás Garcia', - frangarcia: 'Fran García', - dustindclark: 'Dustin Clark' ] + licenses { + license { + name = "The Apache License, Version 2.0" + url = "http://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "graemerocher" + name = 'Graeme Rocher' + } + developer { + id = "puneetbehl" + name = 'Puneet Behl' + } + developer { + id = "nwwells" + name = 'Nathan Wells' + } + developer { + id = "tulu" + name = 'Ruben' + } + developer { + id = "arturoojeda" + name = 'Arturo Ojeda López' + } + developer { + id = "fabiooshiro" + name = 'Fabio Issamu Oshiro' + } + developer { + id = "ddelponte" + name = 'Dean Del Ponte' + } + developer { + id = "cristallo" + name = 'Cristiano Limiti' + } + developer { + id = "mirweb" + name = 'Mirko Weber' + } + developer { + id = "joasgarcia" + name = 'Joás Garcia' + } + developer { + id = "frangarcia" + name = 'Fran García' + } + developer { + id = "dustindclark" + name = 'Dustin Clark' + } + developer { + id = "miq" + name = 'Mihael Koep' + email = 'mihael.koep@softwareschneiderei.de' + } + } + } + + versionMapping { + usage('java-api') { + fromResolutionOf('runtimeClasspath') + } + usage('java-runtime') { + fromResolutionResult() + } + } + from components.java + repositories { + maven { + credentials { + username "$mavenUser" + password "$mavenPassword" + } + url "$mavenUrl" + } + } + } + } } diff --git a/gradle.properties b/gradle.properties index bdfdba0..b666168 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,5 @@ grailsVersion=5.3.6 grailsGradlePluginVersion=5.3.1 org.gradle.daemon=true org.gradle.parallel=true -org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx1024M \ No newline at end of file +org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx1024M +org.gradle.logging.level=info diff --git a/gradle/publish.gradle b/gradle/publish.gradle index fb15ed4..67c9451 100644 --- a/gradle/publish.gradle +++ b/gradle/publish.gradle @@ -39,8 +39,6 @@ if (bintrayProperties.exists()) { } } -// Publish gh-pages on github -apply plugin: "org.ajoberstar.github-pages" File githubProperties = project.rootProject.file('github.properties') if (githubProperties.exists()) { diff --git a/grails-app/controllers/grails/plugins/export/TestController.groovy b/grails-app/controllers/grails/plugins/export/TestController.groovy index 40713ac..8375632 100644 --- a/grails-app/controllers/grails/plugins/export/TestController.groovy +++ b/grails-app/controllers/grails/plugins/export/TestController.groovy @@ -4,13 +4,19 @@ class TestController { def exportService def index() { - def list = [[name:'Grails', version:'5.0']] - String ext = params.extension?:params.format - if (ext in ['csv', 'xls', 'ods', 'pdf', 'rtf', 'xml']) { + def data = [[name:'Grails', version:'5.0', 'current date': new Date()]] + String ext = params.extension ?: params.format + if (ext in ['csv', 'xls', 'xlsx', 'ods', 'pdf', 'rtf', 'xml']) { response.setHeader("Content-disposition", "attachment; filename=test.${ext}") - exportService.export(ext == 'xls'?'excel':ext, response.outputStream, list, [:], [:]) - } else { - respond list + def parameters = [ + 'fileFormat': ext, + 'dateFormat': 'yyyy-MM-dd HH:mm:SS', + 'column.width.autoSize': true + ] + exportService.export(ext == 'xls' || ext == 'xlsx' ? 'excel' : ext, response.outputStream, data, [:], parameters) + return } + + respond data } } diff --git a/grails-app/services/grails/plugins/export/ExportService.groovy b/grails-app/services/grails/plugins/export/ExportService.groovy index 4b23c96..3a4450e 100644 --- a/grails-app/services/grails/plugins/export/ExportService.groovy +++ b/grails-app/services/grails/plugins/export/ExportService.groovy @@ -6,8 +6,6 @@ import grails.core.GrailsApplication class ExportService { - boolean transactional = false - def exporterFactory GrailsApplication grailsApplication @@ -32,5 +30,4 @@ class ExportService { Exporter exporter = exporterFactory.createExporter(type, fields, labels, formatters, parameters) exporter.export(response.outputStream, objects) } - } diff --git a/grails-app/taglib/grails/plugins/export/ExportTagLib.groovy b/grails-app/taglib/grails/plugins/export/ExportTagLib.groovy index e3266e8..1a7d7a8 100644 --- a/grails-app/taglib/grails/plugins/export/ExportTagLib.groovy +++ b/grails-app/taglib/grails/plugins/export/ExportTagLib.groovy @@ -1,6 +1,7 @@ package grails.plugins.export import grails.plugins.export.taglib.util.RenderUtils +import groovy.xml.MarkupBuilder class ExportTagLib { @@ -8,7 +9,7 @@ class ExportTagLib { def formats = { attrs -> StringWriter writer = new StringWriter() - def builder = new groovy.xml.MarkupBuilder(writer) + def builder = new MarkupBuilder(writer) if(!attrs?.'class'){ attrs.'class' = "export" @@ -27,7 +28,7 @@ class ExportTagLib { attrs.remove("controller") } - List formats = ['csv', 'excel', 'ods', 'pdf', 'rtf', 'xml'] + List formats = ['csv', 'excel 97', 'excel (NEW)', 'ods', 'pdf', 'rtf', 'xml'] if(attrs?.formats){ formats = new ArrayList(attrs.formats) attrs.remove("formats") @@ -39,7 +40,7 @@ class ExportTagLib { attrs.remove("params") } - Map extensions = [excel: "xls"] + Map extensions = ['excel 97': "xls", 'excel (NEW)': 'xlsx'] builder."div"(attrs){ formats.each { format -> @@ -75,7 +76,7 @@ class ExportTagLib { def resource = { attrs -> StringWriter writer = new StringWriter() - def builder = new groovy.xml.MarkupBuilder(writer) + def builder = new MarkupBuilder(writer) String resourcePath = RenderUtils.getResourcePath("export", request?.contextPath) diff --git a/grails-app/views/test/index.gsp b/grails-app/views/test/index.gsp index 797e349..1a4e60b 100644 --- a/grails-app/views/test/index.gsp +++ b/grails-app/views/test/index.gsp @@ -5,6 +5,6 @@ - + \ No newline at end of file diff --git a/src/main/groovy/grails/plugins/export/ExportGrailsPlugin.groovy b/src/main/groovy/grails/plugins/export/ExportGrailsPlugin.groovy index ecef914..54a0708 100644 --- a/src/main/groovy/grails/plugins/export/ExportGrailsPlugin.groovy +++ b/src/main/groovy/grails/plugins/export/ExportGrailsPlugin.groovy @@ -2,7 +2,6 @@ package grails.plugins.export import grails.plugins.Plugin import groovy.util.logging.Commons -import org.apache.log4j.Logger import org.slf4j.LoggerFactory @Commons @@ -59,5 +58,4 @@ and can be extended to add additional formats. log.error("Error initializing Export plugin") } } } - } diff --git a/src/main/groovy/grails/plugins/export/builder/ExcelBuilder.groovy b/src/main/groovy/grails/plugins/export/builder/ExcelBuilder.groovy index b300e87..78a17ed 100644 --- a/src/main/groovy/grails/plugins/export/builder/ExcelBuilder.groovy +++ b/src/main/groovy/grails/plugins/export/builder/ExcelBuilder.groovy @@ -1,32 +1,13 @@ package grails.plugins.export.builder -import groovy.util.BuilderSupport -import jxl.CellView -import jxl.format.Border -import jxl.format.BorderLineStyle -import jxl.format.CellFormat -import jxl.format.Colour -import jxl.format.Pattern -import jxl.write.WritableFont -import jxl.Workbook -import jxl.write.Label -import jxl.write.Number -import jxl.write.DateTime -import jxl.write.WritableCellFormat -import jxl.write.WritableFont -import jxl.write.WritableSheet -import jxl.write.WritableWorkbook -import jxl.write.WriteException -import jxl.write.biff.RowsExceededException -import jxl.write.WritableFont -import jxl.format.UnderlineStyle -import jxl.format.UnderlineStyle -import jxl.write.WritableCellFormat -import jxl.write.biff.CellValue -import jxl.write.WritableFont -import jxl.write.WritableHyperlink -import org.apache.commons.logging.* +import org.apache.poi.common.usermodel.HyperlinkType +import org.apache.poi.hssf.usermodel.HSSFWorkbook +import org.apache.poi.ss.usermodel.* +import org.apache.poi.ss.util.WorkbookUtil +import org.apache.poi.xssf.usermodel.XSSFWorkbook +import org.slf4j.Logger +import org.slf4j.LoggerFactory /** * @author Andreas Schmitt @@ -64,13 +45,16 @@ import org.apache.commons.logging.* class ExcelBuilder extends BuilderSupport { - WritableWorkbook workbook - WritableSheet sheet - + Workbook workbook + Sheet sheet + CellStyle defaultHyperlinkStyle + CellStyle dateCellStyle + boolean autoSizeColumns + String format - Map formats = [:] + Map formats = [:] - private static Log log = LogFactory.getLog(ExcelBuilder) + private static Logger log = LoggerFactory.getLogger(ExcelBuilder.class) /** * This method isn't implemented. @@ -88,11 +72,7 @@ class ExcelBuilder extends BuilderSupport { protected Object createNode(Object name) { log.debug("createNode(Object name)") log.debug("name: ${name}") - - if(name == "write"){ - this.write() - } - + createNode(name, [:]) return null } @@ -118,127 +98,125 @@ class ExcelBuilder extends BuilderSupport { log.debug("createNode(Object name, Map attributes)") log.debug("name: ${name} attributes: ${attributes}") - switch(name){ + switch (name) { // Workbook, the Excel document as such case "workbook": - if(attributes?.outputStream){ - try { - log.debug("Creating workbook") - workbook = Workbook.createWorkbook(attributes?.outputStream) - } - catch(Exception e){ - log.error("Error creating workbook", e) - } - } + try { + log.debug("Creating workbook") + // we support new XLSX file format but default to the old excel 97 file format if not requested otherwise + workbook = attributes?.fileFormat == 'xlsx' ? new XSSFWorkbook() : new HSSFWorkbook() + defaultHyperlinkStyle = createDefaultHyperlinkStyle(workbook) + dateCellStyle = createDateCellStyle(workbook, attributes.dateFormat ?: 'm/d/yy h:mm') + } catch (Exception e) { + log.error("Error creating workbook", e) + } break - // Sheet, an Excel file can contain multiple sheets which are typically shown as tabs case "sheet": try { log.debug("Creating sheet") - sheet = workbook.createSheet(attributes?.name, workbook.getNumberOfSheets()) + sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName(attributes?.name as String)) if (attributes?.widths && !attributes?.widths?.isEmpty()) { attributes.widths.eachWithIndex { width, i -> - sheet.setColumnView(i, (width < 1.0 ? width * 100 : width) as int ) + sheet.setColumnWidth(i, (width < 1.0 ? width * 100 : width) as int) } } else { - if(attributes?.widthAutoSize){ - for(int i = 0; i < attributes.numberOfFields - 1; i++){ - sheet.setColumnView(i, new CellView(autosize: true)) - } - } + autoSizeColumns = attributes?.widthAutoSize as boolean } - } - catch(Exception e){ + } catch(Exception e) { log.error("Error creating sheet", e) } break - // Cell, column header or row cells case "cell": try { - CellValue value - if(attributes?.value instanceof java.lang.Number){ + Row row = sheet.getRow(attributes?.row as int) ?: sheet.createRow(attributes?.row as int) + Cell cell + def value = attributes?.value + def valueString = attributes?.value?.toString() + if (value instanceof Number) { log.debug("Creating number cell") - value = new Number(attributes?.column, attributes?.row, attributes?.value) - } else if(attributes?.value instanceof Date){ + cell = row.createCell(attributes?.column as int, CellType.NUMERIC) + } else if (value instanceof Date) { log.debug("Creating date cell") - value = new DateTime(attributes?.column, attributes?.row, attributes?.value) - } - else { + cell = row.createCell(attributes?.column as int) + cell.cellStyle = dateCellStyle + } else if (valueString?.toLowerCase()?.startsWith('http://') || valueString?.toLowerCase()?.startsWith('https://')) { + // Create hyperlinks for values beginning with http + log.debug("Changing cell to Hyperlink") + Hyperlink link = workbook.getCreationHelper().createHyperlink(HyperlinkType.URL) + link.setAddress(valueString) + cell = row.createCell(attributes?.column as int) + cell.setHyperlink(link) + cell.setCellStyle(defaultHyperlinkStyle) + value = valueString ?: 'no URL' + } else { log.debug("Creating label cell") - value = new Label(attributes?.column, attributes?.row, attributes?.value?.toString()) + cell = row.createCell(attributes?.column as int, CellType.STRING) } - - if(attributes?.format && formats.containsKey(attributes?.format)){ - value.setCellFormat(formats[attributes.format]) - } - - // Create hyperlinks for values beginning with http - if (attributes?.value?.toString()?.toLowerCase()?.startsWith('http://') || attributes?.value?.toString()?.toLowerCase()?.startsWith('https://')) { - log.debug("Changing cell to Hyperlink") - def link = new WritableHyperlink(attributes?.column, attributes?.row, new URL(attributes?.value?.toString())) - link.setDescription(attributes?.value?.toString() ?: 'no URL') - sheet.addHyperlink(link); + cell.setCellValue(value) + sheet.autoSizeColumn(cell.columnIndex) + if (attributes?.format && formats.containsKey(attributes?.format)) { + cell.setCellStyle(formats[attributes.format]) } - else { - sheet.addCell(value) - } - } - catch(Exception e){ + } catch (Exception e) { log.error("Error adding cell with attributes: ${attributes}", e) } break - case "format": - if(attributes?.name){ + if (attributes?.name){ format = attributes?.name } break - case "font": try { log.debug("attributes: ${attributes}") attributes.name = attributes?.name ? attributes?.name : "arial" attributes.italic = attributes?.italic ? attributes?.italic : false - attributes.bold = attributes?.bold ? attributes?.bold : "false" - attributes["size"] = attributes["size"] ? attributes["size"] : WritableFont.DEFAULT_POINT_SIZE + attributes.bold = attributes?.bold ? Boolean.valueOf(attributes?.bold as String) : false + attributes["size"] = attributes["size"] ? attributes["size"] : 10 attributes.underline = attributes?.underline ? attributes?.underline : "none" - //attributes.backColor = attributes?.backColor ? attributes?.backColor : Colour.WHITE - attributes.foreColor = attributes?.foreColor ? attributes?.foreColor : Colour.BLACK + attributes.foreColor = attributes?.foreColor ? attributes?.foreColor : IndexedColors.BLACK.index attributes.useBorder = attributes?.useBorder ? attributes?.useBorder : false - Map bold = ["true": WritableFont.BOLD, "false": WritableFont.NO_BOLD] - if(bold.containsKey(attributes.bold.toString())){ - attributes.bold = bold[attributes?.bold.toString()] - } - - Map underline = ["none": UnderlineStyle.NO_UNDERLINE, "double accounting": UnderlineStyle.DOUBLE_ACCOUNTING, - "single": UnderlineStyle.SINGLE, "single accounting": UnderlineStyle.SINGLE_ACCOUNTING] - if(underline.containsKey(attributes.underline)){ + Map underline = ["none": Font.U_NONE, "double accounting": Font.U_DOUBLE_ACCOUNTING, + "single": Font.U_SINGLE, "single accounting": Font.U_SINGLE_ACCOUNTING] + if (underline.containsKey(attributes.underline)) { attributes.underline = underline[attributes.underline] } - - Map fontname = ["arial": WritableFont.ARIAL, "courier": WritableFont.COURIER, - "tahoma": WritableFont.TAHOMA, "times": WritableFont.TIMES] - if(fontname.containsKey(attributes.name)){ + Map fontname = ["arial": "Arial", "courier": "Courier New", + "tahoma": "Tahoma", "times": "Times New Roman"] + if (fontname.containsKey(attributes.name)) { attributes.name = fontname[attributes.name] } log.debug("attributes: ${attributes}") - WritableFont font = new WritableFont(attributes.name, attributes["size"], attributes.bold, attributes.italic, attributes.underline) - font.colour = attributes.foreColor - WritableCellFormat cellFormat = new WritableCellFormat(font) + Font font = workbook.createFont() + font.bold = attributes.bold as boolean + font.underline = attributes.underline as byte + font.fontHeightInPoints = attributes.size as short + font.fontName = attributes.name as String + font.italic = attributes.italic as boolean + font.color = attributes.foreColor as short + CellStyle style = workbook.createCellStyle() + style.font = font - if (attributes.useBorder) cellFormat.setBorder(Border.ALL, BorderLineStyle.THIN) - if (attributes.backColor) cellFormat.setBackground(attributes.backColor) - if (attributes.alignment) cellFormat.setAlignment(attributes.alignment) - - formats.put(format, cellFormat) - } - catch(Exception e){ + if (attributes.useBorder) { + style.borderBottom = BorderStyle.THIN + style.borderLeft = BorderStyle.THIN + style.borderTop = BorderStyle.THIN + style.borderRight = BorderStyle.THIN + } + if (attributes.backColor) { + style.setFillBackgroundColor(attributes.backColor as short) + } + if (attributes.alignment) { + style.alignment = attributes.alignment as HorizontalAlignment + } + formats.put(format, style) + } catch (Exception e) { println "Error!" e.printStackTrace(); } @@ -256,7 +234,22 @@ class ExcelBuilder extends BuilderSupport { return null } - /** + private static CellStyle createDefaultHyperlinkStyle(Workbook wb) { + def style = wb.createCellStyle() + Font hyperLinkFont = wb.createFont() + hyperLinkFont.setUnderline(Font.U_SINGLE) + hyperLinkFont.setColor(IndexedColors.BLUE.getIndex()) + style.setFont(hyperLinkFont) + return style + } + + private static CellStyle createDateCellStyle(Workbook wb, String format) { + def style = wb.createCellStyle() + style.setDataFormat(wb.creationHelper.createDataFormat().getFormat(format)) + return style + } + + /** * This method isn't implemented. */ protected Object createNode(Object name, Map attributes, Object value) { @@ -268,16 +261,15 @@ class ExcelBuilder extends BuilderSupport { /** * Finish writing the document. */ - public void write(){ + void write(OutputStream targetStream) { log.debug("Writing document") - try { - workbook.write() - workbook.close() - } - catch(Exception e){ + workbook.write(targetStream) + } catch (IOException e) { log.error("Error writing document", e) - } + } finally { + targetStream.flush() + targetStream.close() + } } - -} \ No newline at end of file +} diff --git a/src/main/groovy/grails/plugins/export/exporter/DefaultCSVExporter.groovy b/src/main/groovy/grails/plugins/export/exporter/DefaultCSVExporter.groovy index 9335944..0700f73 100644 --- a/src/main/groovy/grails/plugins/export/exporter/DefaultCSVExporter.groovy +++ b/src/main/groovy/grails/plugins/export/exporter/DefaultCSVExporter.groovy @@ -1,6 +1,7 @@ package grails.plugins.export.exporter -import au.com.bytecode.opencsv.CSVWriter +import com.opencsv.CSVWriter + /** * @author Andreas Schmitt @@ -25,7 +26,7 @@ class DefaultCSVExporter extends AbstractExporter { } // Get stream writer considering charsets - CSVWriter writer = new CSVWriter(getOutputStreamWriter(outputStream), separator, quoteCharacter, lineEnd) + CSVWriter writer = new CSVWriter(getOutputStreamWriter(outputStream), separator, quoteCharacter, quoteCharacter, lineEnd) // Enable/Disable header output boolean isHeaderEnabled = true @@ -61,4 +62,4 @@ class DefaultCSVExporter extends AbstractExporter { throw new ExportingException("Error during export", e) } } -} \ No newline at end of file +} diff --git a/src/main/groovy/grails/plugins/export/exporter/DefaultExcelExporter.groovy b/src/main/groovy/grails/plugins/export/exporter/DefaultExcelExporter.groovy index b23e828..b42e6a0 100644 --- a/src/main/groovy/grails/plugins/export/exporter/DefaultExcelExporter.groovy +++ b/src/main/groovy/grails/plugins/export/exporter/DefaultExcelExporter.groovy @@ -2,8 +2,8 @@ package grails.plugins.export.exporter import grails.plugins.export.builder.ExcelBuilder import groovy.util.logging.Log -import jxl.format.Alignment -import jxl.format.Colour +import org.apache.poi.ss.usermodel.HorizontalAlignment +import org.apache.poi.ss.usermodel.IndexedColors /** * @author Andreas Schmitt @@ -12,23 +12,23 @@ import jxl.format.Colour @Log class DefaultExcelExporter extends AbstractExporter { - protected void exportData(OutputStream outputStream, List data, List fields) throws ExportingException{ + protected void exportData(OutputStream outputStream, List data, List fields) throws ExportingException { try { def builder = new ExcelBuilder() // Enable/Disable header output boolean isHeaderEnabled = true - if(getParameters().containsKey("header.enabled")){ + if (getParameters().containsKey("header.enabled")) { isHeaderEnabled = getParameters().get("header.enabled") } boolean useZebraStyle = false - if(getParameters().containsKey("zebraStyle.enabled")){ + if (getParameters().containsKey("zebraStyle.enabled")) { useZebraStyle = getParameters().get("zebraStyle.enabled") } int maxPerSheet = 60000 - if(getParameters().containsKey("max.rows.persheet")){ + if (getParameters().containsKey("max.rows.persheet")) { maxPerSheet = getParameters().get("max.rows.persheet") } @@ -36,33 +36,36 @@ class DefaultExcelExporter extends AbstractExporter { def startIndex = 0 def endIndex = limitPerSheet + def fileFormat = getParameters().get('fileFormat') + builder { - workbook(outputStream: outputStream){ - for(int j=1; j<=sheets; j++){ + workbook(fileFormat: fileFormat, dateFormat: getParameters().get('dateFormat')){ + for (int j = 1; j <= sheets; j++) { def dataPerSheet = data.subList(startIndex, endIndex) - sheet(name: getParameters().get("title")+"-$j" ?: "Export-$j", widths: getParameters().get("column.widths"), numberOfFields: dataPerSheet.size(), widthAutoSize: getParameters().get("column.width.autoSize")) { + def sheetTitle = getParameters().get("title") + sheet(name: sheetTitle ? "$sheetTitle-$j" : "Export-$j", widths: getParameters().get("column.widths"), numberOfFields: fields.size(), widthAutoSize: getParameters().get("column.width.autoSize")) { format(name: "title") { - Alignment alignment = Alignment.GENERAL + HorizontalAlignment alignment = HorizontalAlignment.GENERAL if (getParameters().containsKey('titles.alignment')) { - alignment = Alignment."${getParameters().get('titles.alignment')}" + alignment = HorizontalAlignment."${getParameters().get('titles.alignment')}" } font(name: "arial", bold: true, size: 14, alignment: alignment) } format(name: "header") { if (useZebraStyle) { - font(name: "arial", bold: true, backColor: Colour.GRAY_80, foreColor: Colour.WHITE, useBorder: true) + font(name: "arial", bold: true, backColor: IndexedColors.GREY_80_PERCENT.index, foreColor: IndexedColors.WHITE.index, useBorder: true) } else { // Use default header format font(name: "arial", bold: true) } } format(name: "odd") { - font(backColor: Colour.GRAY_25, useBorder: true) + font(backColor: IndexedColors.GREY_25_PERCENT.index, useBorder: true) } format(name: "even") { - font(backColor: Colour.WHITE, useBorder: true) + font(backColor: IndexedColors.WHITE.index, useBorder: true) } int rowIndex = 0 @@ -101,26 +104,25 @@ class DefaultExcelExporter extends AbstractExporter { } startIndex = endIndex - endIndex = endIndex+limitPerSheet > data.size() ? data.size() : endIndex+limitPerSheet + endIndex = endIndex + limitPerSheet > data.size() ? data.size() : endIndex + limitPerSheet } } } - builder.write() - } - catch(Exception e){ + builder.write(outputStream) + } catch (Exception e) { throw new ExportingException("Error during export", e) } } - private computeSheetsAndLimit(List data, maxPerSheet) { - if(!data) - throw new ExportingException("Error during export: Empty data!") - + private static computeSheetsAndLimit(List data, maxPerSheet) { + if (!data) { + return [1, 0] + } + def limitPerSheet = data.size() > maxPerSheet ? maxPerSheet : data.size() def sheetsCount = Math.ceil(data.size()/limitPerSheet) log.fine "limitPerSheet:$limitPerSheet ::: sheetsCount:$sheetsCount" return [sheetsCount, limitPerSheet] } - -} \ No newline at end of file +}