├── .github ├── .lycheeignore ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── question.yml │ ├── enhancement.yml │ └── bug_report.yml ├── workflows │ ├── sync-labels.yml │ ├── broken-links.yml │ ├── test-deploy.yml │ └── check-build.yml └── labels.yml ├── assets ├── demo.avif └── preview.gif ├── .idea ├── codeStyles │ ├── codeStyleConfig.xml │ └── Project.xml ├── externalDependencies.xml ├── inspectionProfiles │ └── Project_Default.xml ├── PMDPlugin.xml ├── saveactions_settings.xml └── checkstyle-idea.xml ├── .mvn └── wrapper │ └── maven-wrapper.properties ├── SECURITY.md ├── vaadin-grid-exporter └── src │ ├── main │ ├── resources │ │ └── META-INF │ │ │ └── resources │ │ │ └── frontend │ │ │ └── styles │ │ │ └── wizard.css │ └── java │ │ └── software │ │ └── xdev │ │ └── vaadin │ │ └── grid_exporter │ │ ├── format │ │ ├── SpecificConfig.java │ │ ├── Format.java │ │ ├── AbstractFormat.java │ │ └── SpecificConfigComponent.java │ │ ├── components │ │ └── wizard │ │ │ ├── WizardState.java │ │ │ ├── buttonbar │ │ │ ├── WizardButtonBar.java │ │ │ ├── WizardButtonBarWithAnchor.java │ │ │ └── AbstractWizardButtonBar.java │ │ │ ├── panel │ │ │ └── WizardPanelActions.java │ │ │ ├── step │ │ │ ├── WizardStep.java │ │ │ ├── WizardPanelStepChangedEvent.java │ │ │ ├── WizardStepState.java │ │ │ └── WizardStepComposite.java │ │ │ └── WizardStyles.java │ │ ├── Translator.java │ │ ├── jasper │ │ ├── config │ │ │ ├── highlight │ │ │ │ ├── HighlightConfig.java │ │ │ │ └── HighlightConfigComponent.java │ │ │ ├── title │ │ │ │ ├── TitleConfig.java │ │ │ │ └── TitleConfigComponent.java │ │ │ ├── header │ │ │ │ ├── HeaderConfig.java │ │ │ │ └── HeaderConfigComponent.java │ │ │ ├── separator │ │ │ │ ├── CSVSeparatorConfig.java │ │ │ │ └── CSVSeparatorConfigComponent.java │ │ │ ├── encoding │ │ │ │ ├── ExportEncoding.java │ │ │ │ ├── EncodingConfig.java │ │ │ │ └── EncodingConfigComponent.java │ │ │ ├── JasperConfigsLocalization.java │ │ │ └── page │ │ │ │ ├── PageConfig.java │ │ │ │ └── PageConfigComponent.java │ │ ├── DynamicExporter.java │ │ ├── format │ │ │ ├── OdtFormat.java │ │ │ ├── OdsFormat.java │ │ │ ├── XlsxFormat.java │ │ │ ├── DocxFormat.java │ │ │ ├── TextFormat.java │ │ │ ├── HtmlFormat.java │ │ │ ├── RtfFormat.java │ │ │ ├── PdfFormat.java │ │ │ ├── PptxFormat.java │ │ │ ├── AbstractJasperReportSpreadsheetFormat.java │ │ │ ├── AbstractJasperReportWordProcessingFormat.java │ │ │ └── CsvFormat.java │ │ ├── JasperGridExporterProvider.java │ │ └── JasperGridReportStyles.java │ │ ├── column │ │ ├── headerresolving │ │ │ ├── ColumnHeaderResolvingStrategy.java │ │ │ ├── VaadinColumnHeaderResolvingStrategy.java │ │ │ └── ManualColumnHeaderResolvingStrategy.java │ │ ├── ColumnConfigurationBuilder.java │ │ ├── ColumnConfiguration.java │ │ └── ColumnConfigurationHeaderResolvingStrategyBuilder.java │ │ ├── wizard │ │ ├── steps │ │ │ ├── AbstractGridExportWizardStepComposite.java │ │ │ ├── PreviewStep.java │ │ │ └── FormatStep.java │ │ ├── GridExporterWizardState.java │ │ └── GridExporterWizard.java │ │ ├── GridExporterProvider.java │ │ ├── GridExportLocalizationConfig.java │ │ ├── grid │ │ └── GridDataExtractor.java │ │ └── GridExporter.java │ └── test │ └── java │ └── software │ └── xdev │ └── vaadin │ └── grid_exporter │ ├── grid │ └── GridDataExtractorReflectionTest.java │ └── column │ └── headerresolving │ └── VaadinColumnHeaderResolvingStrategyTest.java ├── .config └── checkstyle │ ├── suppressions.xml │ └── checkstyle.xml ├── .gitattributes ├── vaadin-grid-exporter-demo └── src │ └── main │ ├── resources │ └── application.yml │ └── java │ └── software │ └── xdev │ └── vaadin │ ├── gridexport │ └── example │ │ ├── jsonext │ │ ├── JsonGridExporterProvider.java │ │ ├── JsonConfig.java │ │ ├── JsonConfigComponent.java │ │ └── JsonFormat.java │ │ ├── pre_defined_title │ │ └── PredefinedTitleProvider.java │ │ └── DemoView.java │ └── Application.java ├── renovate.json5 ├── .run └── Run Demo.run.xml ├── .gitignore ├── CHANGELOG.md ├── pom.xml ├── README.md └── CONTRIBUTING.md /.github/.lycheeignore: -------------------------------------------------------------------------------- 1 | # Ignorefile for broken link check 2 | localhost 3 | mvnrepository.com 4 | -------------------------------------------------------------------------------- /assets/demo.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdev-software/vaadin-grid-exporter/HEAD/assets/demo.avif -------------------------------------------------------------------------------- /assets/preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdev-software/vaadin-grid-exporter/HEAD/assets/preview.gif -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | wrapperVersion=3.3.4 2 | distributionType=only-script 3 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip 4 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | Please report a security vulnerability [on GitHub Security Advisories](https://github.com/xdev-software/vaadin-grid-exporter/security/advisories/new). 6 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/resources/META-INF/resources/frontend/styles/wizard.css: -------------------------------------------------------------------------------- 1 | .wizard-panel-content { 2 | overflow-y: auto; 3 | } 4 | 5 | vaadin-tabs.wizard-panel-tabs vaadin-tab::before { 6 | display: none; 7 | } 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: 💬 Contact support 3 | url: https://xdev.software/en/services/support 4 | about: "If you need support as soon as possible or/and you can't wait for any pull request" 5 | -------------------------------------------------------------------------------- /.config/checkstyle/suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Force sh files to have LF 5 | *.sh text eol=lf 6 | 7 | # Force MVN Wrapper Linux files LF 8 | mvnw text eol=lf 9 | maven-wrapper.properties text eol=lf 10 | -------------------------------------------------------------------------------- /.idea/externalDependencies.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /vaadin-grid-exporter-demo/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | vaadin: 2 | allowed-packages: software/xdev,com/vaadin/flow 3 | devmode: 4 | usageStatistics: 5 | enabled: false 6 | 7 | spring: 8 | devtools: 9 | restart: 10 | poll-interval: 2s 11 | quiet-period: 1s 12 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /vaadin-grid-exporter-demo/src/main/java/software/xdev/vaadin/gridexport/example/jsonext/JsonGridExporterProvider.java: -------------------------------------------------------------------------------- 1 | package software.xdev.vaadin.gridexport.example.jsonext; 2 | 3 | import software.xdev.vaadin.grid_exporter.GridExporterProvider; 4 | 5 | 6 | public class JsonGridExporterProvider extends GridExporterProvider 7 | { 8 | public JsonGridExporterProvider() 9 | { 10 | super(JsonConfigComponent.DEFAULT_VALUES, new JsonFormat()); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.idea/PMDPlugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 14 | 16 | -------------------------------------------------------------------------------- /.github/workflows/sync-labels.yml: -------------------------------------------------------------------------------- 1 | name: Sync labels 2 | 3 | on: 4 | push: 5 | branches: develop 6 | paths: 7 | - .github/labels.yml 8 | 9 | workflow_dispatch: 10 | 11 | permissions: 12 | issues: write 13 | 14 | jobs: 15 | labels: 16 | runs-on: ubuntu-latest 17 | timeout-minutes: 10 18 | steps: 19 | - uses: actions/checkout@v5 20 | with: 21 | sparse-checkout: .github/labels.yml 22 | 23 | - uses: EndBug/label-sync@52074158190acb45f3077f9099fea818aa43f97a # v2 24 | with: 25 | config-file: .github/labels.yml 26 | -------------------------------------------------------------------------------- /renovate.json5: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "rebaseWhen": "behind-base-branch", 4 | "packageRules": [ 5 | { 6 | "description": "Ignore project internal dependencies", 7 | "packagePattern": "^software.xdev:vaadin-grid-exporter", 8 | "datasources": [ 9 | "maven" 10 | ], 11 | "enabled": false 12 | }, 13 | { 14 | "description": "Group net.sourceforge.pmd", 15 | "matchPackagePatterns": [ 16 | "^net.sourceforge.pmd" 17 | ], 18 | "datasources": [ 19 | "maven" 20 | ], 21 | "groupName": "net.sourceforge.pmd" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /.run/Run Demo.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /vaadin-grid-exporter-demo/src/main/java/software/xdev/vaadin/gridexport/example/jsonext/JsonConfig.java: -------------------------------------------------------------------------------- 1 | package software.xdev.vaadin.gridexport.example.jsonext; 2 | 3 | import software.xdev.vaadin.grid_exporter.format.SpecificConfig; 4 | 5 | 6 | public class JsonConfig implements SpecificConfig 7 | { 8 | protected boolean usePrettyPrint = true; 9 | 10 | protected boolean withKeys = true; 11 | 12 | public boolean isUsePrettyPrint() 13 | { 14 | return this.usePrettyPrint; 15 | } 16 | 17 | public void setUsePrettyPrint(final boolean usePrettyPrint) 18 | { 19 | this.usePrettyPrint = usePrettyPrint; 20 | } 21 | 22 | public boolean isWithKeys() 23 | { 24 | return this.withKeys; 25 | } 26 | 27 | public void setWithKeys(final boolean withKeys) 28 | { 29 | this.withKeys = withKeys; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/format/SpecificConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.format; 17 | 18 | public interface SpecificConfig 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /vaadin-grid-exporter-demo/src/main/java/software/xdev/vaadin/Application.java: -------------------------------------------------------------------------------- 1 | package software.xdev.vaadin; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 6 | 7 | import com.vaadin.flow.component.page.AppShellConfigurator; 8 | import com.vaadin.flow.component.page.Push; 9 | import com.vaadin.flow.spring.annotation.EnableVaadin; 10 | 11 | 12 | @SuppressWarnings({"checkstyle:HideUtilityClassConstructor", "PMD.UseUtilityClass"}) 13 | @SpringBootApplication 14 | @EnableVaadin 15 | @Push 16 | public class Application extends SpringBootServletInitializer implements AppShellConfigurator 17 | { 18 | public static void main(final String[] args) 19 | { 20 | SpringApplication.run(Application.class, args); 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /.idea/saveactions_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/components/wizard/WizardState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.components.wizard; 17 | 18 | public interface WizardState 19 | { 20 | // just marker 21 | } 22 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/Translator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter; 17 | 18 | /** 19 | * Simple interface to translate a given key into some language. 20 | */ 21 | @FunctionalInterface 22 | public interface Translator 23 | { 24 | /** 25 | * @param key to translate 26 | * @return translated String 27 | */ 28 | String translate(final String key); 29 | } 30 | -------------------------------------------------------------------------------- /.idea/checkstyle-idea.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11.0.0 5 | JavaOnlyWithTests 6 | true 7 | true 8 | 12 | 19 | 20 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | # Default 2 | ## Required for template 3 | - name: bug 4 | description: "Something isn't working" 5 | color: 'd73a4a' 6 | - name: enhancement 7 | description: New feature or request 8 | color: '#a2eeef' 9 | - name: question 10 | description: Information is requested 11 | color: '#d876e3' 12 | ## Others 13 | - name: duplicate 14 | description: This already exists 15 | color: '#cfd3d7' 16 | - name: good first issue 17 | description: Good for newcomers 18 | color: '#7057ff' 19 | - name: help wanted 20 | description: Extra attention is needed 21 | color: '#008672' 22 | - name: invalid 23 | description: "This doesn't seem right" 24 | color: '#e4e669' 25 | # Custom 26 | - name: automated 27 | description: Created by an automation 28 | color: '#000000' 29 | - name: "can't reproduce" 30 | color: '#e95f2c' 31 | - name: customer-requested 32 | description: Was requested by a customer of us 33 | color: '#068374' 34 | - name: stale 35 | color: '#ededed' 36 | - name: waiting-for-response 37 | description: If no response is received after a certain time the issue will be closed 38 | color: '#202020' 39 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/components/wizard/buttonbar/WizardButtonBar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.components.wizard.buttonbar; 17 | 18 | import software.xdev.vaadin.grid_exporter.components.wizard.panel.WizardPanelActions; 19 | 20 | 21 | public class WizardButtonBar extends AbstractWizardButtonBar 22 | { 23 | public WizardButtonBar(final WizardPanelActions panel) 24 | { 25 | this.init(panel); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.yml: -------------------------------------------------------------------------------- 1 | name: ❓ Question 2 | description: Ask a question 3 | labels: [question] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thanks for taking the time to fill out this form! 9 | 10 | - type: checkboxes 11 | id: checklist 12 | attributes: 13 | label: "Checklist" 14 | options: 15 | - label: "I made sure that there are *no existing issues* - [open](https://github.com/xdev-software/vaadin-grid-exporter/issues) or [closed](https://github.com/xdev-software/vaadin-grid-exporter/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to." 16 | required: true 17 | - label: "I have taken the time to fill in all the required details. I understand that the question will be dismissed otherwise." 18 | required: true 19 | 20 | - type: textarea 21 | id: what-is-the-question 22 | attributes: 23 | label: What is/are your question(s)? 24 | validations: 25 | required: true 26 | 27 | - type: textarea 28 | id: additional-information 29 | attributes: 30 | label: Additional information 31 | description: "Any other information you'd like to include - for instance logs, screenshots, etc." 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement.yml: -------------------------------------------------------------------------------- 1 | name: ✨ Feature/Enhancement 2 | description: Suggest a new feature or enhancement 3 | labels: [enhancement] 4 | type: feature 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thank you for suggesting a new feature/enhancement. 10 | 11 | - type: checkboxes 12 | id: checklist 13 | attributes: 14 | label: "Checklist" 15 | options: 16 | - label: "I made sure that there are *no existing issues* - [open](https://github.com/xdev-software/vaadin-grid-exporter/issues) or [closed](https://github.com/xdev-software/vaadin-grid-exporter/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to." 17 | required: true 18 | - label: "I have taken the time to fill in all the required details. I understand that the feature request will be dismissed otherwise." 19 | required: true 20 | - label: "This issue contains only one feature request/enhancement." 21 | required: true 22 | 23 | - type: textarea 24 | id: description 25 | attributes: 26 | label: Description 27 | validations: 28 | required: true 29 | 30 | - type: textarea 31 | id: additional-information 32 | attributes: 33 | label: Additional information 34 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/config/highlight/HighlightConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.config.highlight; 17 | 18 | import software.xdev.vaadin.grid_exporter.format.SpecificConfig; 19 | 20 | 21 | public class HighlightConfig implements SpecificConfig 22 | { 23 | protected boolean highlightOddRows; 24 | 25 | public boolean isHighlightOddRows() 26 | { 27 | return this.highlightOddRows; 28 | } 29 | 30 | public void setHighlightOddRows(final boolean highlightOddRows) 31 | { 32 | this.highlightOddRows = highlightOddRows; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/components/wizard/panel/WizardPanelActions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.components.wizard.panel; 17 | 18 | import java.util.function.Consumer; 19 | 20 | import software.xdev.vaadin.grid_exporter.components.wizard.step.WizardStepState; 21 | 22 | 23 | public interface WizardPanelActions 24 | { 25 | void showFirstStep(final boolean isFromClient); 26 | 27 | void showPreviousStep(final boolean isFromClient); 28 | 29 | void showNextStep(final boolean isFromClient); 30 | 31 | void addStepStateChangedListener(final Consumer newStateConsumer); 32 | } 33 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/config/title/TitleConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.config.title; 17 | 18 | import java.util.Objects; 19 | 20 | import software.xdev.vaadin.grid_exporter.format.SpecificConfig; 21 | 22 | 23 | public class TitleConfig implements SpecificConfig 24 | { 25 | protected String title; 26 | 27 | public String getTitle() 28 | { 29 | return this.title; 30 | } 31 | 32 | public void setTitle(final String title) 33 | { 34 | this.title = Objects.requireNonNull(title); 35 | } 36 | 37 | public boolean notTitleEmpty() 38 | { 39 | return this.getTitle() != null && !this.getTitle().isBlank(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/DynamicExporter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper; 17 | 18 | import software.xdev.dynamicreports.jasper.base.export.AbstractJasperExporter; 19 | import software.xdev.dynamicreports.jasper.builder.JasperReportBuilder; 20 | import software.xdev.dynamicreports.jasper.builder.export.AbstractJasperExporterBuilder; 21 | import software.xdev.dynamicreports.report.exception.DRException; 22 | 23 | 24 | @FunctionalInterface 25 | public interface DynamicExporter> 26 | { 27 | void export(JasperReportBuilder builder, B exportBuilder) throws DRException; 28 | } 29 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/format/OdtFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.format; 17 | 18 | import software.xdev.dynamicreports.jasper.builder.JasperReportBuilder; 19 | import software.xdev.dynamicreports.jasper.builder.export.Exporters; 20 | import software.xdev.dynamicreports.jasper.builder.export.JasperOdtExporterBuilder; 21 | 22 | 23 | public class OdtFormat extends AbstractJasperReportWordProcessingFormat 24 | { 25 | public OdtFormat() 26 | { 27 | super( 28 | "Open Document Text (odt)", 29 | "odt", 30 | "application/vnd.oasis.opendocument.text", 31 | JasperReportBuilder::toOdt, 32 | Exporters::odtExporter 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/config/header/HeaderConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.config.header; 17 | 18 | import software.xdev.vaadin.grid_exporter.format.SpecificConfig; 19 | 20 | 21 | public class HeaderConfig implements SpecificConfig 22 | { 23 | protected boolean exportHeader; 24 | 25 | public HeaderConfig() 26 | { 27 | this(true); 28 | } 29 | 30 | public HeaderConfig(final boolean exportHeader) 31 | { 32 | this.exportHeader = exportHeader; 33 | } 34 | 35 | public boolean isExportHeader() 36 | { 37 | return this.exportHeader; 38 | } 39 | 40 | public void setExportHeader(final boolean exportHeader) 41 | { 42 | this.exportHeader = exportHeader; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/format/OdsFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.format; 17 | 18 | import software.xdev.dynamicreports.jasper.builder.JasperReportBuilder; 19 | import software.xdev.dynamicreports.jasper.builder.export.Exporters; 20 | import software.xdev.dynamicreports.jasper.builder.export.JasperOdsExporterBuilder; 21 | 22 | 23 | public class OdsFormat extends AbstractJasperReportSpreadsheetFormat 24 | { 25 | public OdsFormat() 26 | { 27 | super( 28 | "Open Document Spreadsheet (ods)", 29 | "ods", 30 | "application/vnd.oasis.opendocument.spreadsheet", 31 | JasperReportBuilder::toOds, 32 | Exporters::odsExporter 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/format/XlsxFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.format; 17 | 18 | import software.xdev.dynamicreports.jasper.builder.JasperReportBuilder; 19 | import software.xdev.dynamicreports.jasper.builder.export.Exporters; 20 | import software.xdev.dynamicreports.jasper.builder.export.JasperXlsxExporterBuilder; 21 | 22 | 23 | public class XlsxFormat extends AbstractJasperReportSpreadsheetFormat 24 | { 25 | public XlsxFormat() 26 | { 27 | super( 28 | "Excel (xlsx)", 29 | "xlsx", 30 | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 31 | JasperReportBuilder::toXlsx, 32 | Exporters::xlsxExporter 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/config/separator/CSVSeparatorConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.config.separator; 17 | 18 | import java.util.Objects; 19 | 20 | import software.xdev.vaadin.grid_exporter.format.SpecificConfig; 21 | 22 | 23 | public class CSVSeparatorConfig implements SpecificConfig 24 | { 25 | protected String separator = ";"; 26 | 27 | public String getSeparator() 28 | { 29 | return this.separator; 30 | } 31 | 32 | public void setSeparator(final String separator) 33 | { 34 | Objects.requireNonNull(separator); 35 | if(separator.isEmpty()) 36 | { 37 | throw new IllegalArgumentException("Separator can't be empty"); 38 | } 39 | this.separator = separator; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/format/DocxFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.format; 17 | 18 | import software.xdev.dynamicreports.jasper.builder.JasperReportBuilder; 19 | import software.xdev.dynamicreports.jasper.builder.export.Exporters; 20 | import software.xdev.dynamicreports.jasper.builder.export.JasperDocxExporterBuilder; 21 | 22 | 23 | public class DocxFormat extends AbstractJasperReportWordProcessingFormat 24 | { 25 | public DocxFormat() 26 | { 27 | super( 28 | "Word (docx)", 29 | "docx", 30 | "application/vnd.openxmlformats-officedocument.wordprocessingml.document", 31 | JasperReportBuilder::toDocx, 32 | Exporters::docxExporter 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/components/wizard/step/WizardStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.components.wizard.step; 17 | 18 | import software.xdev.vaadin.grid_exporter.components.wizard.WizardState; 19 | 20 | 21 | public interface WizardStep 22 | { 23 | String getStepName(); 24 | 25 | void setWizardState(S state); 26 | 27 | default void onEnterStep(final S state) 28 | { 29 | // optional 30 | } 31 | 32 | /** 33 | * Called when next is clicked and the current step is exited 34 | * @param state The current state 35 | * @return false when the exit can't happen due to e.g. validation problems. 36 | */ 37 | default boolean onProgress(final S state) 38 | { 39 | // optional 40 | return true; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/config/encoding/ExportEncoding.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.config.encoding; 17 | 18 | import java.nio.charset.Charset; 19 | 20 | 21 | public class ExportEncoding 22 | { 23 | protected final Charset charset; 24 | protected final String bom; 25 | 26 | public ExportEncoding(final Charset charset) 27 | { 28 | this(charset, null); 29 | } 30 | 31 | public ExportEncoding(final Charset charset, final String bom) 32 | { 33 | this.charset = charset; 34 | this.bom = bom; 35 | } 36 | 37 | public Charset charset() 38 | { 39 | return this.charset; 40 | } 41 | 42 | public String bom() 43 | { 44 | return this.bom; 45 | } 46 | 47 | public boolean hasBom() 48 | { 49 | return this.bom() != null; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/format/TextFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.format; 17 | 18 | import software.xdev.dynamicreports.jasper.builder.JasperReportBuilder; 19 | import software.xdev.dynamicreports.jasper.builder.export.Exporters; 20 | import software.xdev.dynamicreports.jasper.builder.export.JasperTextExporterBuilder; 21 | import software.xdev.vaadin.grid_exporter.jasper.config.header.HeaderConfigComponent; 22 | 23 | 24 | public class TextFormat extends AbstractJasperReportFormat 25 | { 26 | public TextFormat() 27 | { 28 | super( 29 | "Text", 30 | "txt", 31 | "text/plain", 32 | false, 33 | false, 34 | JasperReportBuilder::toText, 35 | Exporters::textExporter 36 | ); 37 | this.withConfigComponents( 38 | HeaderConfigComponent::new 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/column/headerresolving/ColumnHeaderResolvingStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.column.headerresolving; 17 | 18 | 19 | 20 | import java.util.Optional; 21 | 22 | import com.vaadin.flow.component.grid.Grid.Column; 23 | 24 | 25 | /** 26 | * Can be implemented to create a new strategy that resolves a {@link Column} header 27 | */ 28 | public interface ColumnHeaderResolvingStrategy 29 | { 30 | /** 31 | * Resolves the text for a column header 32 | * 33 | * @param column 34 | * The column for which the header text should be resolved 35 | * @return 36 | * {@link Optional#empty()} when the text could not be resolved and the next function should be used.
37 | * If a value was found the Optional contains the string. 38 | */ 39 | Optional resolve(Column column); 40 | } 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Maven 2 | target/ 3 | dependency-reduced-pom.xml 4 | 5 | # Maven Wrapper 6 | .mvn/wrapper/maven-wrapper.jar 7 | 8 | # Maven Flatten Plugin 9 | .flattened-pom.xml 10 | 11 | # Compiled class file 12 | *.class 13 | 14 | # Log file 15 | *.log 16 | 17 | # Package/Binary Files don't belong into a git repo 18 | *.jar 19 | *.war 20 | *.ear 21 | *.zip 22 | *.tar.gz 23 | *.dll 24 | *.exe 25 | *.bin 26 | 27 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 28 | hs_err_pid* 29 | 30 | # Eclipse 31 | .metadata 32 | .settings 33 | .classpath 34 | .project 35 | 36 | #vaadin/node webpack/frontend stuff 37 | # Ignore Node 38 | node/ 39 | 40 | # The following files are generated/updated by vaadin-maven-plugin 41 | node_modules/ 42 | 43 | # Vaadin 44 | package.json 45 | package-lock.json 46 | webpack.generated.js 47 | webpack.config.js 48 | tsconfig.json 49 | types.d.ts 50 | vite.config.ts 51 | vite.generated.ts 52 | **/src/main/frontend/generated/ 53 | **/src/main/frontend/index.html 54 | **/src/main/bundles/ 55 | *.lock 56 | 57 | 58 | # == IntelliJ == 59 | *.iml 60 | *.ipr 61 | 62 | # Some files are user/installation independent and are used for configuring the IDE 63 | # See also https://stackoverflow.com/a/35279076 64 | 65 | .idea/* 66 | !.idea/saveactions_settings.xml 67 | !.idea/checkstyle-idea.xml 68 | !.idea/externalDependencies.xml 69 | !.idea/PMDPlugin.xml 70 | 71 | !.idea/inspectionProfiles/ 72 | .idea/inspectionProfiles/* 73 | !.idea/inspectionProfiles/Project_Default.xml 74 | 75 | !.idea/codeStyles/ 76 | .idea/codeStyles/* 77 | !.idea/codeStyles/codeStyleConfig.xml 78 | !.idea/codeStyles/Project.xml 79 | -------------------------------------------------------------------------------- /.github/workflows/broken-links.yml: -------------------------------------------------------------------------------- 1 | name: Broken links 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: "23 23 * * 0" 7 | 8 | permissions: 9 | issues: write 10 | 11 | jobs: 12 | link-checker: 13 | runs-on: ubuntu-latest 14 | timeout-minutes: 15 15 | steps: 16 | - uses: actions/checkout@v5 17 | 18 | - run: mv .github/.lycheeignore .lycheeignore 19 | 20 | - name: Link Checker 21 | id: lychee 22 | uses: lycheeverse/lychee-action@885c65f3dc543b57c898c8099f4e08c8afd178a2 # v2 23 | with: 24 | fail: false # Don't fail on broken links, create an issue instead 25 | 26 | - name: Find already existing issue 27 | id: find-issue 28 | run: | 29 | echo "number=$(gh issue list -l 'bug' -l 'automated' -L 1 -S 'in:title "Link Checker Report"' -s 'open' --json 'number' --jq '.[].number')" >> $GITHUB_OUTPUT 30 | env: 31 | GH_TOKEN: ${{ github.token }} 32 | 33 | - name: Close issue if everything is fine 34 | if: steps.lychee.outputs.exit_code == 0 && steps.find-issue.outputs.number != '' 35 | run: gh issue close -r 'not planned' ${{ steps.find-issue.outputs.number }} 36 | env: 37 | GH_TOKEN: ${{ github.token }} 38 | 39 | - name: Create Issue From File 40 | if: steps.lychee.outputs.exit_code != 0 41 | uses: peter-evans/create-issue-from-file@fca9117c27cdc29c6c4db3b86c48e4115a786710 # v6 42 | with: 43 | issue-number: ${{ steps.find-issue.outputs.number }} 44 | title: Link Checker Report 45 | content-filepath: ./lychee/out.md 46 | labels: bug, automated 47 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/components/wizard/step/WizardPanelStepChangedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.components.wizard.step; 17 | 18 | import java.util.Objects; 19 | 20 | import com.vaadin.flow.component.ComponentEvent; 21 | 22 | import software.xdev.vaadin.grid_exporter.components.wizard.WizardState; 23 | import software.xdev.vaadin.grid_exporter.components.wizard.panel.WizardPanel; 24 | 25 | @SuppressWarnings("java:S1948") 26 | public class WizardPanelStepChangedEvent extends ComponentEvent> 27 | { 28 | protected final WizardStepState stepState; 29 | 30 | public WizardPanelStepChangedEvent( 31 | final WizardStepState stepState, 32 | final WizardPanel source, 33 | final boolean fromClient) 34 | { 35 | super(source, fromClient); 36 | this.stepState = Objects.requireNonNull(stepState); 37 | } 38 | 39 | public WizardStepState getStepState() 40 | { 41 | return this.stepState; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/format/Format.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.format; 17 | 18 | import java.util.List; 19 | import java.util.function.Function; 20 | 21 | import software.xdev.vaadin.grid_exporter.Translator; 22 | import software.xdev.vaadin.grid_exporter.column.ColumnConfiguration; 23 | import software.xdev.vaadin.grid_exporter.grid.GridDataExtractor; 24 | 25 | 26 | /** 27 | * Defines a format to export grid data to. 28 | */ 29 | public interface Format 30 | { 31 | String getFormatNameToDisplay(); 32 | 33 | String getFormatFilenameSuffix(); 34 | 35 | String getMimeType(); 36 | 37 | // Either ignore a rawtype or a generic wildcard type warning 38 | @SuppressWarnings("java:S1452") 39 | List>> getConfigComponents(); 40 | 41 | byte[] export( 42 | GridDataExtractor gridDataExtractor, 43 | List> columnsToExport, 44 | List configs); 45 | } 46 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/wizard/steps/AbstractGridExportWizardStepComposite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.wizard.steps; 17 | 18 | import java.util.Objects; 19 | 20 | import com.vaadin.flow.component.Component; 21 | 22 | import software.xdev.vaadin.grid_exporter.Translator; 23 | import software.xdev.vaadin.grid_exporter.components.wizard.step.WizardStepComposite; 24 | import software.xdev.vaadin.grid_exporter.wizard.GridExporterWizardState; 25 | 26 | @SuppressWarnings("java:S1948") 27 | public abstract class AbstractGridExportWizardStepComposite 28 | extends WizardStepComposite> 29 | implements Translator 30 | { 31 | protected Translator translator; 32 | 33 | protected AbstractGridExportWizardStepComposite(final Translator translator) 34 | { 35 | this.translator = Objects.requireNonNull(translator); 36 | } 37 | 38 | @Override 39 | public String translate(final String key) 40 | { 41 | return this.translator.translate(key); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/column/ColumnConfigurationBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.column; 17 | 18 | 19 | 20 | import java.util.function.Consumer; 21 | 22 | import com.vaadin.flow.component.grid.Grid.Column; 23 | 24 | 25 | /** 26 | * Used for (initially) building a {@link ColumnConfiguration} 27 | */ 28 | public class ColumnConfigurationBuilder 29 | { 30 | protected final ColumnConfigurationHeaderResolvingStrategyBuilder columnConfigHeaderResolvingStrategyBuilder = 31 | new ColumnConfigurationHeaderResolvingStrategyBuilder(); 32 | 33 | public ColumnConfigurationBuilder withColumnConfigHeaderResolvingStrategyBuilder( 34 | final Consumer configureBuilderFunc) 35 | { 36 | configureBuilderFunc.accept(this.columnConfigHeaderResolvingStrategyBuilder); 37 | return this; 38 | } 39 | 40 | public ColumnConfiguration build(final Column gridColumn) 41 | { 42 | return new ColumnConfiguration<>(gridColumn, this.columnConfigHeaderResolvingStrategyBuilder.build()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/components/wizard/step/WizardStepState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.components.wizard.step; 17 | 18 | public class WizardStepState 19 | { 20 | protected final int currentStep; 21 | protected final int totalSteps; 22 | 23 | public WizardStepState(final int currentStep, final int totalSteps) 24 | { 25 | if(totalSteps < 0) 26 | { 27 | throw new IllegalArgumentException("Total steps is invalid"); 28 | } 29 | if(currentStep < 0 || currentStep > totalSteps) 30 | { 31 | throw new IllegalArgumentException("Current step is invalid"); 32 | } 33 | 34 | this.currentStep = currentStep; 35 | this.totalSteps = totalSteps; 36 | } 37 | 38 | public int getCurrentStep() 39 | { 40 | return this.currentStep; 41 | } 42 | 43 | public int getTotalSteps() 44 | { 45 | return this.totalSteps; 46 | } 47 | 48 | public boolean isFirstStep() 49 | { 50 | return this.getCurrentStep() <= 1; 51 | } 52 | 53 | public boolean isLastStep() 54 | { 55 | return this.getCurrentStep() >= this.getTotalSteps(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/config/title/TitleConfigComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.config.title; 17 | 18 | import com.vaadin.flow.component.textfield.TextField; 19 | 20 | import software.xdev.vaadin.grid_exporter.Translator; 21 | import software.xdev.vaadin.grid_exporter.format.SpecificConfigComponent; 22 | import software.xdev.vaadin.grid_exporter.jasper.config.JasperConfigsLocalization; 23 | 24 | 25 | public class TitleConfigComponent extends SpecificConfigComponent 26 | { 27 | protected final TextField txtTitle = new TextField(); 28 | 29 | public TitleConfigComponent(final Translator translator) 30 | { 31 | super(translator, TitleConfig::new, JasperConfigsLocalization.TITLE); 32 | 33 | this.initUIs(); 34 | 35 | this.registerBindings(); 36 | } 37 | 38 | protected void initUIs() 39 | { 40 | this.getContent().add(this.txtTitle); 41 | } 42 | 43 | protected void registerBindings() 44 | { 45 | this.binder.forField(this.txtTitle) 46 | .bind(TitleConfig::getTitle, TitleConfig::setTitle); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/components/wizard/step/WizardStepComposite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.components.wizard.step; 17 | 18 | import com.vaadin.flow.component.Component; 19 | import com.vaadin.flow.component.Composite; 20 | 21 | import software.xdev.vaadin.grid_exporter.components.wizard.WizardState; 22 | 23 | @SuppressWarnings("java:S1948") 24 | public abstract class WizardStepComposite 25 | extends Composite 26 | implements WizardStep 27 | { 28 | protected String stepName = ""; 29 | protected S state; 30 | 31 | protected WizardStepComposite() 32 | { 33 | this.setStepName(this.getClass().getSimpleName()); 34 | } 35 | 36 | @Override 37 | public String getStepName() 38 | { 39 | return this.stepName; 40 | } 41 | 42 | public void setStepName(final String stepName) 43 | { 44 | this.stepName = stepName; 45 | } 46 | 47 | public S getWizardState() 48 | { 49 | return this.state; 50 | } 51 | 52 | @Override 53 | public void setWizardState(final S state) 54 | { 55 | this.state = state; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/format/HtmlFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.format; 17 | 18 | import software.xdev.dynamicreports.jasper.builder.JasperReportBuilder; 19 | import software.xdev.dynamicreports.jasper.builder.export.Exporters; 20 | import software.xdev.dynamicreports.jasper.builder.export.JasperHtmlExporterBuilder; 21 | import software.xdev.vaadin.grid_exporter.jasper.config.header.HeaderConfigComponent; 22 | import software.xdev.vaadin.grid_exporter.jasper.config.highlight.HighlightConfigComponent; 23 | import software.xdev.vaadin.grid_exporter.jasper.config.title.TitleConfigComponent; 24 | 25 | 26 | public class HtmlFormat extends AbstractJasperReportFormat 27 | { 28 | public HtmlFormat() 29 | { 30 | super( 31 | "HTML", 32 | "html", 33 | "text/html", 34 | false, 35 | true, 36 | JasperReportBuilder::toHtml, 37 | Exporters::htmlExporter 38 | ); 39 | this.withConfigComponents( 40 | TitleConfigComponent::new, 41 | HeaderConfigComponent::new, 42 | HighlightConfigComponent::new 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/components/wizard/WizardStyles.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.components.wizard; 17 | 18 | public final class WizardStyles 19 | { 20 | private WizardStyles() 21 | { 22 | // No impl 23 | } 24 | 25 | public static final String LOCATION = "./styles/wizard.css"; 26 | 27 | // region WizardPanel 28 | 29 | public static final String WIZARD_PANEL = "wizard-panel"; 30 | 31 | public static final String WIZARD_PANEL_TABS = WIZARD_PANEL + "-tabs"; 32 | 33 | public static final String WIZARD_PANEL_CONTENT = WIZARD_PANEL + "-content"; 34 | 35 | // endregion 36 | // region WizardButtonBar 37 | 38 | public static final String WIZARD_BUTTON_BAR = "wizard-button-bar"; 39 | 40 | public static final String WIZARD_BUTTON_BAR_BTN_CANCEL = WIZARD_BUTTON_BAR + "-cancel"; 41 | public static final String WIZARD_BUTTON_BAR_BTN_PREVIOUS = WIZARD_BUTTON_BAR + "-previous"; 42 | public static final String WIZARD_BUTTON_BAR_BTN_NEXT = WIZARD_BUTTON_BAR + "-next"; 43 | public static final String WIZARD_BUTTON_BAR_BTN_DONE = WIZARD_BUTTON_BAR + "-done"; 44 | 45 | // endregion 46 | } 47 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/column/headerresolving/VaadinColumnHeaderResolvingStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.column.headerresolving; 17 | 18 | import java.util.Optional; 19 | 20 | import com.vaadin.flow.component.Component; 21 | import com.vaadin.flow.component.grid.Grid.Column; 22 | import com.vaadin.flow.dom.Element; 23 | 24 | 25 | /** 26 | * Tries to get the header using Vaadin Column API methods 27 | *

28 | * Note: This might fail when the vaadin version changes 29 | */ 30 | public class VaadinColumnHeaderResolvingStrategy implements ColumnHeaderResolvingStrategy 31 | { 32 | @Override 33 | public Optional resolve(final Column column) 34 | { 35 | try 36 | { 37 | final Optional optHeaderComponentText = Optional.ofNullable(column.getHeaderComponent()) 38 | .map(Component::getElement) 39 | .map(Element::getText); 40 | if(optHeaderComponentText.isPresent()) 41 | { 42 | return optHeaderComponentText; 43 | } 44 | 45 | return Optional.ofNullable(column.getHeaderText()); 46 | } 47 | catch(final Exception e) 48 | { 49 | return Optional.empty(); 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /vaadin-grid-exporter-demo/src/main/java/software/xdev/vaadin/gridexport/example/jsonext/JsonConfigComponent.java: -------------------------------------------------------------------------------- 1 | package software.xdev.vaadin.gridexport.example.jsonext; 2 | 3 | import static java.util.Map.entry; 4 | 5 | import java.util.Map; 6 | 7 | import com.vaadin.flow.component.checkbox.Checkbox; 8 | 9 | import software.xdev.vaadin.grid_exporter.Translator; 10 | import software.xdev.vaadin.grid_exporter.format.SpecificConfigComponent; 11 | 12 | 13 | public class JsonConfigComponent extends SpecificConfigComponent 14 | { 15 | public static final String JSON = "json"; 16 | 17 | public static final String USE_PRETTY_PRINT = "use_pretty_print"; 18 | 19 | public static final String WITH_KEYS = "with_keys"; 20 | 21 | // Key, Default Value 22 | public static final Map DEFAULT_VALUES = Map.ofEntries( 23 | entry(JSON, "JSON"), 24 | entry(USE_PRETTY_PRINT, "Use pretty print"), 25 | entry(WITH_KEYS, "Export with keys") 26 | ); 27 | 28 | protected final Checkbox chbxUsePrettyPrint = new Checkbox(); 29 | 30 | protected final Checkbox chbxWithKeys = new Checkbox(); 31 | 32 | protected JsonConfigComponent(final Translator translator) 33 | { 34 | super(translator, JsonConfig::new, JSON); 35 | 36 | this.initUI(); 37 | 38 | this.registerBindings(); 39 | } 40 | 41 | protected void initUI() 42 | { 43 | this.chbxUsePrettyPrint.setLabel(this.translate(USE_PRETTY_PRINT)); 44 | 45 | this.chbxWithKeys.setLabel(this.translate(WITH_KEYS)); 46 | 47 | this.getContent().add(this.chbxUsePrettyPrint, this.chbxWithKeys); 48 | } 49 | 50 | protected void registerBindings() 51 | { 52 | this.binder.forField(this.chbxUsePrettyPrint) 53 | .bind(JsonConfig::isUsePrettyPrint, JsonConfig::setUsePrettyPrint); 54 | 55 | this.binder.forField(this.chbxWithKeys) 56 | .bind(JsonConfig::isWithKeys, JsonConfig::setWithKeys); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/config/separator/CSVSeparatorConfigComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.config.separator; 17 | 18 | import com.vaadin.flow.component.textfield.TextField; 19 | 20 | import software.xdev.vaadin.grid_exporter.Translator; 21 | import software.xdev.vaadin.grid_exporter.format.SpecificConfigComponent; 22 | import software.xdev.vaadin.grid_exporter.jasper.config.JasperConfigsLocalization; 23 | 24 | 25 | public class CSVSeparatorConfigComponent extends SpecificConfigComponent 26 | { 27 | protected final TextField txtSeparator = new TextField(); 28 | 29 | public CSVSeparatorConfigComponent(final Translator translator) 30 | { 31 | super(translator, CSVSeparatorConfig::new, JasperConfigsLocalization.SEPARATOR); 32 | 33 | this.initUIs(); 34 | 35 | this.registerBindings(); 36 | } 37 | 38 | protected void initUIs() 39 | { 40 | this.getContent().add(this.txtSeparator); 41 | } 42 | 43 | protected void registerBindings() 44 | { 45 | this.binder.forField(this.txtSeparator) 46 | .asRequired() 47 | .bind(CSVSeparatorConfig::getSeparator, CSVSeparatorConfig::setSeparator); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/format/RtfFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.format; 17 | 18 | import software.xdev.dynamicreports.jasper.builder.JasperReportBuilder; 19 | import software.xdev.dynamicreports.jasper.builder.export.Exporters; 20 | import software.xdev.dynamicreports.jasper.builder.export.JasperRtfExporterBuilder; 21 | import software.xdev.vaadin.grid_exporter.jasper.config.header.HeaderConfigComponent; 22 | import software.xdev.vaadin.grid_exporter.jasper.config.page.PageConfigComponent; 23 | import software.xdev.vaadin.grid_exporter.jasper.config.title.TitleConfigComponent; 24 | 25 | 26 | public class RtfFormat extends AbstractJasperReportFormat 27 | { 28 | public RtfFormat() 29 | { 30 | super( 31 | "Rich Text", 32 | "rtf", 33 | "text/rtf", 34 | true, 35 | false, 36 | JasperReportBuilder::toRtf, 37 | Exporters::rtfExporter 38 | ); 39 | this.withConfigComponents( 40 | TitleConfigComponent::new, 41 | // Don't export header by default because it's centered? 42 | translator -> new HeaderConfigComponent(translator, false), 43 | PageConfigComponent::new 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/GridExporterProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter; 17 | 18 | import java.util.Arrays; 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | import software.xdev.vaadin.grid_exporter.format.Format; 23 | 24 | 25 | /** 26 | * Provides data to the {@link GridExporter}. 27 | *

28 | * Can be used for extensions. 29 | *

30 | */ 31 | public class GridExporterProvider 32 | { 33 | protected final Map defaultTranslationKeyValues; 34 | protected final List formats; 35 | 36 | public GridExporterProvider(final Map defaultTranslationKeyValues, final Format... formats) 37 | { 38 | this(defaultTranslationKeyValues, Arrays.asList(formats)); 39 | } 40 | 41 | public GridExporterProvider(final Map defaultTranslationKeyValues, final List formats) 42 | { 43 | this.defaultTranslationKeyValues = defaultTranslationKeyValues; 44 | this.formats = formats; 45 | } 46 | 47 | public Map getDefaultTranslationKeyValues() 48 | { 49 | return this.defaultTranslationKeyValues; 50 | } 51 | 52 | public List getFormats() 53 | { 54 | return this.formats; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/format/PdfFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.format; 17 | 18 | import software.xdev.dynamicreports.jasper.builder.JasperReportBuilder; 19 | import software.xdev.dynamicreports.jasper.builder.export.Exporters; 20 | import software.xdev.dynamicreports.jasper.builder.export.JasperPdfExporterBuilder; 21 | import software.xdev.vaadin.grid_exporter.jasper.config.header.HeaderConfigComponent; 22 | import software.xdev.vaadin.grid_exporter.jasper.config.highlight.HighlightConfigComponent; 23 | import software.xdev.vaadin.grid_exporter.jasper.config.page.PageConfigComponent; 24 | import software.xdev.vaadin.grid_exporter.jasper.config.title.TitleConfigComponent; 25 | 26 | 27 | public class PdfFormat extends AbstractJasperReportFormat 28 | { 29 | 30 | public PdfFormat() 31 | { 32 | super( 33 | "PDF", 34 | "pdf", 35 | "application/pdf", 36 | true, 37 | true, 38 | JasperReportBuilder::toPdf, 39 | Exporters::pdfExporter 40 | ); 41 | this.withConfigComponents( 42 | TitleConfigComponent::new, 43 | HeaderConfigComponent::new, 44 | HighlightConfigComponent::new, 45 | PageConfigComponent::new 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/config/highlight/HighlightConfigComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.config.highlight; 17 | 18 | import com.vaadin.flow.component.checkbox.Checkbox; 19 | 20 | import software.xdev.vaadin.grid_exporter.Translator; 21 | import software.xdev.vaadin.grid_exporter.format.SpecificConfigComponent; 22 | import software.xdev.vaadin.grid_exporter.jasper.config.JasperConfigsLocalization; 23 | 24 | 25 | public class HighlightConfigComponent extends SpecificConfigComponent 26 | { 27 | protected final Checkbox chbxExportHeader = new Checkbox(); 28 | 29 | public HighlightConfigComponent(final Translator translator) 30 | { 31 | super(translator, HighlightConfig::new, JasperConfigsLocalization.HIGHLIGHTING); 32 | 33 | this.initUI(); 34 | 35 | this.registerBindings(); 36 | } 37 | 38 | protected void initUI() 39 | { 40 | this.chbxExportHeader.setLabel(this.translate(JasperConfigsLocalization.HIGHLIGHT_ROWS)); 41 | 42 | this.getContent().add(this.chbxExportHeader); 43 | } 44 | 45 | protected void registerBindings() 46 | { 47 | this.binder.forField(this.chbxExportHeader) 48 | .bind(HighlightConfig::isHighlightOddRows, HighlightConfig::setHighlightOddRows); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/components/wizard/buttonbar/WizardButtonBarWithAnchor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.components.wizard.buttonbar; 17 | 18 | import com.vaadin.flow.component.html.Anchor; 19 | 20 | import software.xdev.vaadin.grid_exporter.components.wizard.panel.WizardPanelActions; 21 | import software.xdev.vaadin.grid_exporter.components.wizard.step.WizardStepState; 22 | 23 | 24 | public class WizardButtonBarWithAnchor extends AbstractWizardButtonBar 25 | { 26 | protected final Anchor anchorDone = new Anchor(); 27 | 28 | public WizardButtonBarWithAnchor(final WizardPanelActions panel) 29 | { 30 | this.init(panel); 31 | } 32 | 33 | @Override 34 | protected void initUI() 35 | { 36 | super.initUI(); 37 | 38 | this.hlEndButtons.remove(this.btnDone); 39 | this.hlEndButtons.add(this.anchorDone); 40 | 41 | this.btnDone.setDisableOnClick(false); 42 | this.anchorDone.add(this.btnDone); 43 | } 44 | 45 | @Override 46 | protected void updateFromStepState(final WizardStepState stepState) 47 | { 48 | super.updateFromStepState(stepState); 49 | 50 | this.getAnchorDone().setVisible(this.getBtnDone().isVisible()); 51 | } 52 | 53 | public Anchor getAnchorDone() 54 | { 55 | return this.anchorDone; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/format/PptxFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.format; 17 | 18 | import software.xdev.dynamicreports.jasper.builder.JasperReportBuilder; 19 | import software.xdev.dynamicreports.jasper.builder.export.Exporters; 20 | import software.xdev.dynamicreports.jasper.builder.export.JasperPptxExporterBuilder; 21 | import software.xdev.vaadin.grid_exporter.jasper.config.header.HeaderConfigComponent; 22 | import software.xdev.vaadin.grid_exporter.jasper.config.highlight.HighlightConfigComponent; 23 | import software.xdev.vaadin.grid_exporter.jasper.config.page.PageConfigComponent; 24 | import software.xdev.vaadin.grid_exporter.jasper.config.title.TitleConfigComponent; 25 | 26 | 27 | public class PptxFormat extends AbstractJasperReportFormat 28 | { 29 | public PptxFormat() 30 | { 31 | super( 32 | "Powerpoint (pptx)", 33 | "pptx", 34 | "application/vnd.openxmlformats-officedocument.presentationml.presentation", 35 | true, 36 | true, 37 | JasperReportBuilder::toPptx, 38 | Exporters::pptxExporter 39 | ); 40 | this.withConfigComponents( 41 | TitleConfigComponent::new, 42 | HeaderConfigComponent::new, 43 | HighlightConfigComponent::new, 44 | PageConfigComponent::new 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /.github/workflows/test-deploy.yml: -------------------------------------------------------------------------------- 1 | name: Test Deployment 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | env: 7 | PRIMARY_MAVEN_MODULE: ${{ github.event.repository.name }} 8 | 9 | jobs: 10 | publish-maven: 11 | runs-on: ubuntu-latest 12 | timeout-minutes: 60 13 | steps: 14 | - uses: actions/checkout@v5 15 | 16 | - name: Set up JDK 17 | uses: actions/setup-java@v5 18 | with: # running setup-java overwrites the settings.xml 19 | distribution: 'temurin' 20 | java-version: '17' 21 | server-id: github-central 22 | server-password: PACKAGES_CENTRAL_TOKEN 23 | gpg-passphrase: MAVEN_GPG_PASSPHRASE 24 | gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Only import once 25 | 26 | - name: Publish to GitHub Packages Central 27 | run: ../mvnw -B deploy -P publish -DskipTests -DaltDeploymentRepository=github-central::https://maven.pkg.github.com/xdev-software/central 28 | working-directory: ${{ env.PRIMARY_MAVEN_MODULE }} 29 | env: 30 | PACKAGES_CENTRAL_TOKEN: ${{ secrets.PACKAGES_CENTRAL_TOKEN }} 31 | MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} 32 | 33 | - name: Set up JDK 34 | uses: actions/setup-java@v5 35 | with: # running setup-java again overwrites the settings.xml 36 | distribution: 'temurin' 37 | java-version: '17' 38 | server-id: sonatype-central-portal 39 | server-username: MAVEN_CENTRAL_USERNAME 40 | server-password: MAVEN_CENTRAL_TOKEN 41 | gpg-passphrase: MAVEN_GPG_PASSPHRASE 42 | 43 | - name: Publish to Central Portal 44 | run: ../mvnw -B deploy -P publish,publish-sonatype-central-portal -DskipTests 45 | working-directory: ${{ env.PRIMARY_MAVEN_MODULE }} 46 | env: 47 | MAVEN_CENTRAL_USERNAME: ${{ secrets.SONATYPE_MAVEN_CENTRAL_PORTAL_USERNAME }} 48 | MAVEN_CENTRAL_TOKEN: ${{ secrets.SONATYPE_MAVEN_CENTRAL_PORTAL_TOKEN }} 49 | MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} 50 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/config/header/HeaderConfigComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.config.header; 17 | 18 | import com.vaadin.flow.component.checkbox.Checkbox; 19 | 20 | import software.xdev.vaadin.grid_exporter.Translator; 21 | import software.xdev.vaadin.grid_exporter.format.SpecificConfigComponent; 22 | import software.xdev.vaadin.grid_exporter.jasper.config.JasperConfigsLocalization; 23 | 24 | 25 | public class HeaderConfigComponent extends SpecificConfigComponent 26 | { 27 | protected final Checkbox chbxExportHeader = new Checkbox(); 28 | 29 | public HeaderConfigComponent(final Translator translator, final boolean defaultExportHeaderValue) 30 | { 31 | super(translator, () -> new HeaderConfig(defaultExportHeaderValue), JasperConfigsLocalization.HEADER); 32 | 33 | this.initUI(); 34 | 35 | this.registerBindings(); 36 | } 37 | 38 | public HeaderConfigComponent(final Translator translator) 39 | { 40 | this(translator, true); 41 | } 42 | 43 | protected void initUI() 44 | { 45 | this.chbxExportHeader.setLabel(this.translate(JasperConfigsLocalization.EXPORT_HEADER)); 46 | 47 | this.getContent().add(this.chbxExportHeader); 48 | } 49 | 50 | protected void registerBindings() 51 | { 52 | this.binder.forField(this.chbxExportHeader) 53 | .bind(HeaderConfig::isExportHeader, HeaderConfig::setExportHeader); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/column/ColumnConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.column; 17 | 18 | import java.util.Objects; 19 | 20 | import com.vaadin.flow.component.grid.Grid.Column; 21 | import com.vaadin.flow.function.SerializableFunction; 22 | 23 | 24 | public class ColumnConfiguration 25 | { 26 | protected final Column gridColumn; 27 | protected String header; 28 | 29 | public ColumnConfiguration( 30 | final Column gridColumn, 31 | final SerializableFunction, String> headerResolver) 32 | { 33 | this.gridColumn = gridColumn; 34 | this.header = Objects.requireNonNullElse(headerResolver.apply(gridColumn), ""); 35 | } 36 | 37 | public Column getGridColumn() 38 | { 39 | return this.gridColumn; 40 | } 41 | 42 | public String getHeader() 43 | { 44 | return this.header; 45 | } 46 | 47 | public ColumnConfiguration setHeader(final String header) 48 | { 49 | this.header = Objects.requireNonNull(header); 50 | return this; 51 | } 52 | 53 | @Override 54 | public boolean equals(final Object o) 55 | { 56 | if(this == o) 57 | { 58 | return true; 59 | } 60 | if(!(o instanceof final ColumnConfiguration that)) 61 | { 62 | return false; 63 | } 64 | return Objects.equals(this.gridColumn, that.gridColumn); 65 | } 66 | 67 | @Override 68 | public int hashCode() 69 | { 70 | return Objects.hash(this.gridColumn); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/format/AbstractJasperReportSpreadsheetFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.format; 17 | 18 | import java.io.OutputStream; 19 | import java.util.function.Function; 20 | 21 | import software.xdev.dynamicreports.jasper.base.export.AbstractJasperExporter; 22 | import software.xdev.dynamicreports.jasper.builder.export.AbstractJasperExporterBuilder; 23 | import software.xdev.vaadin.grid_exporter.jasper.DynamicExporter; 24 | import software.xdev.vaadin.grid_exporter.jasper.config.header.HeaderConfigComponent; 25 | import software.xdev.vaadin.grid_exporter.jasper.config.highlight.HighlightConfigComponent; 26 | 27 | 28 | public abstract class AbstractJasperReportSpreadsheetFormat> 30 | extends AbstractJasperReportFormat 31 | { 32 | protected AbstractJasperReportSpreadsheetFormat( 33 | final String nameToDisplay, 34 | final String fileSuffix, 35 | final String mimeType, 36 | final DynamicExporter jasperReportBuilderTo, 37 | final Function jasperExportBuilderSupplier) 38 | { 39 | super( 40 | nameToDisplay, 41 | fileSuffix, 42 | mimeType, 43 | false, 44 | true, 45 | jasperReportBuilderTo, 46 | jasperExportBuilderSupplier); 47 | this.withConfigComponents( 48 | HeaderConfigComponent::new, 49 | HighlightConfigComponent::new 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /vaadin-grid-exporter-demo/src/main/java/software/xdev/vaadin/gridexport/example/jsonext/JsonFormat.java: -------------------------------------------------------------------------------- 1 | package software.xdev.vaadin.gridexport.example.jsonext; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | 6 | import com.fasterxml.jackson.core.JsonProcessingException; 7 | import com.fasterxml.jackson.databind.ObjectMapper; 8 | import com.fasterxml.jackson.databind.ObjectWriter; 9 | 10 | import software.xdev.vaadin.grid_exporter.column.ColumnConfiguration; 11 | import software.xdev.vaadin.grid_exporter.format.AbstractFormat; 12 | import software.xdev.vaadin.grid_exporter.format.SpecificConfig; 13 | import software.xdev.vaadin.grid_exporter.grid.GridDataExtractor; 14 | 15 | 16 | public class JsonFormat extends AbstractFormat 17 | { 18 | public JsonFormat() 19 | { 20 | super("JSON", "json", "application/json"); 21 | this.withConfigComponents( 22 | JsonConfigComponent::new 23 | ); 24 | } 25 | 26 | @SuppressWarnings("java:S112") // IDK 27 | @Override 28 | public byte[] export( 29 | final GridDataExtractor gridDataExtractor, 30 | final List> columnsToExport, 31 | final List configs) 32 | { 33 | final ObjectMapper mapper = new ObjectMapper(); 34 | // pretty writer 35 | final ObjectWriter writer = 36 | this.getValueFrom(configs, JsonConfig.class, JsonConfig::isUsePrettyPrint) 37 | .orElse(false) 38 | ? mapper.writerWithDefaultPrettyPrinter() 39 | : mapper.writer(); 40 | 41 | try 42 | { 43 | final List> rowData = 44 | gridDataExtractor.getSortedAndFilteredData(columnsToExport); 45 | return writer.writeValueAsBytes( 46 | this.getValueFrom(configs, JsonConfig.class, JsonConfig::isWithKeys) 47 | .orElse(false) 48 | // Create a key-value Map 49 | ? rowData.stream() 50 | .map(list -> columnsToExport.stream().collect(Collectors.toMap( 51 | ColumnConfiguration::getHeader, 52 | i -> list.get(columnsToExport.indexOf(i)))) 53 | ) 54 | .toList() 55 | : rowData); 56 | } 57 | catch(final JsonProcessingException e) 58 | { 59 | throw new RuntimeException(e); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/config/encoding/EncodingConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.config.encoding; 17 | 18 | import java.nio.charset.StandardCharsets; 19 | import java.util.Arrays; 20 | import java.util.List; 21 | import java.util.Objects; 22 | 23 | import software.xdev.vaadin.grid_exporter.format.SpecificConfig; 24 | 25 | 26 | public class EncodingConfig implements SpecificConfig 27 | { 28 | protected List available = Arrays.asList( 29 | new ExportEncoding(StandardCharsets.UTF_8, "\ufeff"), 30 | new ExportEncoding(StandardCharsets.ISO_8859_1) 31 | ); 32 | protected ExportEncoding selected = this.available.get(0); 33 | protected boolean useBOM; 34 | 35 | public List getAvailable() 36 | { 37 | return this.available; 38 | } 39 | 40 | public void setAvailable(final List available) 41 | { 42 | this.available = Objects.requireNonNull(available); 43 | } 44 | 45 | public ExportEncoding getSelected() 46 | { 47 | return this.selected; 48 | } 49 | 50 | public void setSelected(final ExportEncoding selected) 51 | { 52 | this.selected = selected; 53 | } 54 | 55 | public boolean isUseBOM() 56 | { 57 | return this.useBOM; 58 | } 59 | 60 | public void setUseBOM(final boolean useBOM) 61 | { 62 | this.useBOM = useBOM; 63 | } 64 | 65 | 66 | public boolean supportsAndUseBOM() 67 | { 68 | return this.isUseBOM() && this.getSelected().hasBom(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/JasperGridExporterProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper; 17 | 18 | import java.util.Arrays; 19 | 20 | import software.xdev.vaadin.grid_exporter.GridExporterProvider; 21 | import software.xdev.vaadin.grid_exporter.jasper.config.JasperConfigsLocalization; 22 | import software.xdev.vaadin.grid_exporter.jasper.format.CsvFormat; 23 | import software.xdev.vaadin.grid_exporter.jasper.format.DocxFormat; 24 | import software.xdev.vaadin.grid_exporter.jasper.format.HtmlFormat; 25 | import software.xdev.vaadin.grid_exporter.jasper.format.OdsFormat; 26 | import software.xdev.vaadin.grid_exporter.jasper.format.OdtFormat; 27 | import software.xdev.vaadin.grid_exporter.jasper.format.PdfFormat; 28 | import software.xdev.vaadin.grid_exporter.jasper.format.PptxFormat; 29 | import software.xdev.vaadin.grid_exporter.jasper.format.RtfFormat; 30 | import software.xdev.vaadin.grid_exporter.jasper.format.TextFormat; 31 | import software.xdev.vaadin.grid_exporter.jasper.format.XlsxFormat; 32 | 33 | 34 | public class JasperGridExporterProvider extends GridExporterProvider 35 | { 36 | public JasperGridExporterProvider() 37 | { 38 | super( 39 | JasperConfigsLocalization.DEFAULT_VALUES, 40 | Arrays.asList( 41 | new PdfFormat(), 42 | new XlsxFormat(), 43 | new CsvFormat(), 44 | new DocxFormat(), 45 | new HtmlFormat(), 46 | new OdsFormat(), 47 | new OdtFormat(), 48 | new PptxFormat(), 49 | new RtfFormat(), 50 | new TextFormat() 51 | )); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/format/AbstractJasperReportWordProcessingFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.format; 17 | 18 | import java.io.OutputStream; 19 | import java.util.function.Function; 20 | 21 | import software.xdev.dynamicreports.jasper.base.export.AbstractJasperExporter; 22 | import software.xdev.dynamicreports.jasper.builder.export.AbstractJasperExporterBuilder; 23 | import software.xdev.vaadin.grid_exporter.jasper.DynamicExporter; 24 | import software.xdev.vaadin.grid_exporter.jasper.config.header.HeaderConfigComponent; 25 | import software.xdev.vaadin.grid_exporter.jasper.config.highlight.HighlightConfigComponent; 26 | import software.xdev.vaadin.grid_exporter.jasper.config.page.PageConfigComponent; 27 | import software.xdev.vaadin.grid_exporter.jasper.config.title.TitleConfigComponent; 28 | 29 | 30 | public abstract class AbstractJasperReportWordProcessingFormat> 32 | extends AbstractJasperReportFormat 33 | { 34 | protected AbstractJasperReportWordProcessingFormat( 35 | final String nameToDisplay, 36 | final String fileSuffix, 37 | final String mimeType, 38 | final DynamicExporter jasperReportBuilderTo, 39 | final Function jasperExportBuilderSupplier) 40 | { 41 | super( 42 | nameToDisplay, 43 | fileSuffix, 44 | mimeType, 45 | true, 46 | true, 47 | jasperReportBuilderTo, 48 | jasperExportBuilderSupplier); 49 | this.withConfigComponents( 50 | TitleConfigComponent::new, 51 | HeaderConfigComponent::new, 52 | HighlightConfigComponent::new, 53 | PageConfigComponent::new 54 | ); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/format/CsvFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.format; 17 | 18 | import java.util.List; 19 | 20 | import software.xdev.dynamicreports.jasper.builder.JasperReportBuilder; 21 | import software.xdev.dynamicreports.jasper.builder.export.Exporters; 22 | import software.xdev.dynamicreports.jasper.builder.export.JasperCsvExporterBuilder; 23 | import software.xdev.vaadin.grid_exporter.format.SpecificConfig; 24 | import software.xdev.vaadin.grid_exporter.jasper.config.encoding.EncodingConfigComponent; 25 | import software.xdev.vaadin.grid_exporter.jasper.config.header.HeaderConfigComponent; 26 | import software.xdev.vaadin.grid_exporter.jasper.config.separator.CSVSeparatorConfig; 27 | import software.xdev.vaadin.grid_exporter.jasper.config.separator.CSVSeparatorConfigComponent; 28 | 29 | 30 | public class CsvFormat extends AbstractJasperReportFormat 31 | { 32 | 33 | public CsvFormat() 34 | { 35 | super( 36 | "CSV", 37 | "csv", 38 | "text/comma-separated-value", 39 | false, 40 | false, 41 | JasperReportBuilder::toCsv, 42 | Exporters::csvExporter 43 | ); 44 | this.withConfigComponents( 45 | HeaderConfigComponent::new, 46 | CSVSeparatorConfigComponent::new, 47 | EncodingConfigComponent::new 48 | ); 49 | } 50 | 51 | @Override 52 | protected void export( 53 | final JasperReportBuilder reportBuilder, 54 | final JasperCsvExporterBuilder exportBuilder, 55 | final List configs) 56 | { 57 | this.getValueFrom(configs, CSVSeparatorConfig.class, CSVSeparatorConfig::getSeparator) 58 | .ifPresent(exportBuilder::setFieldDelimiter); 59 | 60 | super.export(reportBuilder, exportBuilder, configs); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: 🐞 Bug 2 | description: Create a bug report for something that is broken 3 | labels: [bug] 4 | type: bug 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thank you for reporting a bug. 10 | 11 | Please fill in as much information as possible about your bug so that we don't have to play "information ping-pong" and can help you immediately. 12 | 13 | - type: checkboxes 14 | id: checklist 15 | attributes: 16 | label: "Checklist" 17 | options: 18 | - label: "I am able to reproduce the bug with the [latest version](https://github.com/xdev-software/vaadin-grid-exporter/releases/latest)" 19 | required: true 20 | - label: "I made sure that there are *no existing issues* - [open](https://github.com/xdev-software/vaadin-grid-exporter/issues) or [closed](https://github.com/xdev-software/vaadin-grid-exporter/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to." 21 | required: true 22 | - label: "I have taken the time to fill in all the required details. I understand that the bug report will be dismissed otherwise." 23 | required: true 24 | - label: "This issue contains only one bug." 25 | required: true 26 | 27 | - type: input 28 | id: app-version 29 | attributes: 30 | label: Affected version 31 | description: "In which version did you encounter the bug?" 32 | placeholder: "x.x.x" 33 | validations: 34 | required: true 35 | 36 | - type: textarea 37 | id: description 38 | attributes: 39 | label: Description of the problem 40 | description: | 41 | Describe as exactly as possible what is not working. 42 | validations: 43 | required: true 44 | 45 | - type: textarea 46 | id: steps-to-reproduce 47 | attributes: 48 | label: Steps to reproduce the bug 49 | description: | 50 | What did you do for the bug to show up? 51 | 52 | If you can't cause the bug to show up again reliably (and hence don't have a proper set of steps to give us), please still try to give as many details as possible on how you think you encountered the bug. 53 | placeholder: | 54 | 1. Use '...' 55 | 2. Do '...' 56 | validations: 57 | required: true 58 | 59 | - type: textarea 60 | id: additional-information 61 | attributes: 62 | label: Additional information 63 | description: | 64 | Any other relevant information you'd like to include 65 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/column/headerresolving/ManualColumnHeaderResolvingStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.column.headerresolving; 17 | 18 | import java.util.Map; 19 | import java.util.Optional; 20 | import java.util.function.Function; 21 | 22 | import com.vaadin.flow.component.grid.Grid.Column; 23 | 24 | 25 | /** 26 | * Resolves the header-text by using the unique identification {@linkplain I} and find the corresponding resolving 27 | * function for the identification in a map. 28 | *
29 | * This function is the used to resolve the header-text. 30 | *

31 | * Example: 32 | *
33 | * {@code new ManualColumnHeaderResolvingStrategy(col -> col.getKey(), Map.of("name", k -> "Username", "pw", k -> 34 | * "Password"))} 35 | *

36 | * 37 | * @param The identifier of the column, e.g. the key or the column itself 38 | */ 39 | public class ManualColumnHeaderResolvingStrategy implements ColumnHeaderResolvingStrategy 40 | { 41 | protected final Function, I> identifierResolver; 42 | protected final Map> headerTextResolverMap; 43 | 44 | public ManualColumnHeaderResolvingStrategy( 45 | final Function, I> identifierResolver, 46 | final Map> headerTextResolverMap) 47 | { 48 | this.identifierResolver = identifierResolver; 49 | this.headerTextResolverMap = headerTextResolverMap; 50 | } 51 | 52 | @Override 53 | public Optional resolve(final Column column) 54 | { 55 | final I identifier = this.identifierResolver.apply(column); 56 | 57 | final Function resolveFunction = this.headerTextResolverMap.get(identifier); 58 | if(resolveFunction == null) 59 | { 60 | return Optional.empty(); 61 | } 62 | 63 | return Optional.ofNullable(resolveFunction.apply(identifier)); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /vaadin-grid-exporter-demo/src/main/java/software/xdev/vaadin/gridexport/example/pre_defined_title/PredefinedTitleProvider.java: -------------------------------------------------------------------------------- 1 | package software.xdev.vaadin.gridexport.example.pre_defined_title; 2 | 3 | import java.util.List; 4 | 5 | import software.xdev.dynamicreports.jasper.builder.JasperReportBuilder; 6 | import software.xdev.dynamicreports.jasper.builder.export.Exporters; 7 | import software.xdev.dynamicreports.jasper.builder.export.JasperPdfExporterBuilder; 8 | import software.xdev.vaadin.grid_exporter.GridExporterProvider; 9 | import software.xdev.vaadin.grid_exporter.Translator; 10 | import software.xdev.vaadin.grid_exporter.jasper.config.JasperConfigsLocalization; 11 | import software.xdev.vaadin.grid_exporter.jasper.config.header.HeaderConfigComponent; 12 | import software.xdev.vaadin.grid_exporter.jasper.config.highlight.HighlightConfigComponent; 13 | import software.xdev.vaadin.grid_exporter.jasper.config.page.PageConfigComponent; 14 | import software.xdev.vaadin.grid_exporter.jasper.config.title.TitleConfig; 15 | import software.xdev.vaadin.grid_exporter.jasper.config.title.TitleConfigComponent; 16 | import software.xdev.vaadin.grid_exporter.jasper.format.AbstractJasperReportFormat; 17 | 18 | 19 | public class PredefinedTitleProvider extends GridExporterProvider 20 | { 21 | public PredefinedTitleProvider(final String predefinedTitle) 22 | { 23 | super( 24 | JasperConfigsLocalization.DEFAULT_VALUES, 25 | List.of( 26 | new PredefinedTitlePdfFormat(predefinedTitle) 27 | )); 28 | } 29 | 30 | public static class PredefinedTitlePdfFormat extends AbstractJasperReportFormat 31 | { 32 | public PredefinedTitlePdfFormat(final String defaultTitle) 33 | { 34 | super( 35 | "PDF", 36 | "pdf", 37 | "application/pdf", 38 | true, 39 | true, 40 | JasperReportBuilder::toPdf, 41 | Exporters::pdfExporter 42 | ); 43 | this.withConfigComponents( 44 | translator -> new PreDefinedTitleConfigComponent(translator, defaultTitle), 45 | HeaderConfigComponent::new, 46 | HighlightConfigComponent::new, 47 | PageConfigComponent::new 48 | ); 49 | } 50 | } 51 | 52 | 53 | public static class PreDefinedTitleConfigComponent extends TitleConfigComponent 54 | { 55 | public PreDefinedTitleConfigComponent(final Translator translator, final String defaultTitle) 56 | { 57 | super(translator); 58 | this.setNewConfigSupplier(() -> { 59 | final TitleConfig titleConfig = new TitleConfig(); 60 | titleConfig.setTitle(defaultTitle); 61 | return titleConfig; 62 | }); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/config/encoding/EncodingConfigComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.config.encoding; 17 | 18 | import com.vaadin.flow.component.checkbox.Checkbox; 19 | import com.vaadin.flow.component.combobox.ComboBox; 20 | 21 | import software.xdev.vaadin.grid_exporter.Translator; 22 | import software.xdev.vaadin.grid_exporter.format.SpecificConfigComponent; 23 | import software.xdev.vaadin.grid_exporter.jasper.config.JasperConfigsLocalization; 24 | 25 | 26 | public class EncodingConfigComponent extends SpecificConfigComponent 27 | { 28 | protected final ComboBox cbExportEncoding = new ComboBox<>(); 29 | protected final Checkbox chbxUseBom = new Checkbox(); 30 | 31 | public EncodingConfigComponent(final Translator translator) 32 | { 33 | super(translator, EncodingConfig::new, JasperConfigsLocalization.ENCODING); 34 | 35 | this.initUI(); 36 | 37 | this.registerBindings(); 38 | } 39 | 40 | protected void initUI() 41 | { 42 | this.cbExportEncoding.setItemLabelGenerator(ee -> ee.charset().name()); 43 | 44 | this.chbxUseBom.setLabel(this.translate(JasperConfigsLocalization.WITH_BOM)); 45 | 46 | this.getContent().add(this.cbExportEncoding, this.chbxUseBom); 47 | } 48 | 49 | protected void registerBindings() 50 | { 51 | this.binder.forField(this.cbExportEncoding) 52 | .asRequired() 53 | .bind(EncodingConfig::getSelected, EncodingConfig::setSelected); 54 | 55 | this.cbExportEncoding.addValueChangeListener(ev -> this.validateAndManageUseBOM(ev.getValue())); 56 | 57 | this.binder.forField(this.chbxUseBom) 58 | .bind(EncodingConfig::isUseBOM, EncodingConfig::setUseBOM); 59 | } 60 | 61 | protected void validateAndManageUseBOM(final ExportEncoding value) 62 | { 63 | if(value == null) 64 | { 65 | return; 66 | } 67 | 68 | this.chbxUseBom.setEnabled(value.hasBom()); 69 | if(!value.hasBom()) 70 | { 71 | this.chbxUseBom.setValue(false); 72 | } 73 | } 74 | 75 | @Override 76 | public void updateFrom(final EncodingConfig value) 77 | { 78 | this.cbExportEncoding.setItems(value.getAvailable()); 79 | 80 | super.updateFrom(value); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/config/JasperConfigsLocalization.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.config; 17 | 18 | import static java.util.Map.entry; 19 | 20 | import java.util.Map; 21 | 22 | 23 | public final class JasperConfigsLocalization 24 | { 25 | private JasperConfigsLocalization() 26 | { 27 | // No impl 28 | } 29 | 30 | public static final String PREFIX = "gridexporter.jasperformats."; 31 | 32 | public static final String ENCODING = PREFIX + "encoding"; 33 | public static final String WITH_BOM = PREFIX + "with_bom"; 34 | 35 | 36 | public static final String HEADER = PREFIX + "header"; 37 | public static final String EXPORT_HEADER = PREFIX + "export_header"; 38 | 39 | public static final String HIGHLIGHTING = PREFIX + "highlighting"; 40 | public static final String HIGHLIGHT_ROWS = PREFIX + "highlight_rows"; 41 | 42 | public static final String PAGE = PREFIX + "page"; 43 | public static final String FORMAT_PAGE_TYPE = PREFIX + "format_page_type"; 44 | public static final String ORIENTATION = PREFIX + "orientation"; 45 | public static final String ORIENTATION_PORTRAIT = ORIENTATION + ".portrait"; 46 | public static final String ORIENTATION_LANDSCAPE = ORIENTATION + ".landscape"; 47 | public static final String SHOW_PAGE_NUMBERS = PREFIX + "show_page_numbers"; 48 | public static final String MARGIN = PREFIX + "margin"; 49 | 50 | public static final String SEPARATOR = PREFIX + "separator"; 51 | 52 | public static final String TITLE = PREFIX + "title"; 53 | 54 | // Key, Default Value 55 | public static final Map DEFAULT_VALUES = Map.ofEntries( 56 | entry(ENCODING, "Encoding"), 57 | entry(WITH_BOM, "with BOM"), 58 | entry(HEADER, "Header"), 59 | entry(EXPORT_HEADER, "Export header"), 60 | entry(HIGHLIGHTING, "Highlighting"), 61 | entry(HIGHLIGHT_ROWS, "Highlight rows"), 62 | entry(PAGE, "Page"), 63 | entry(FORMAT_PAGE_TYPE, "Format / Page type"), 64 | entry(ORIENTATION, "Orientation"), 65 | entry(ORIENTATION_PORTRAIT, "Portrait"), 66 | entry(ORIENTATION_LANDSCAPE, "Landscape"), 67 | entry(SHOW_PAGE_NUMBERS, "Show page numbers"), 68 | entry(MARGIN, "Margin"), 69 | entry(SEPARATOR, "Separator"), 70 | entry(TITLE, "Title") 71 | ); 72 | } 73 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/JasperGridReportStyles.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper; 17 | 18 | import java.awt.Color; 19 | 20 | import software.xdev.dynamicreports.report.builder.style.SimpleStyleBuilder; 21 | import software.xdev.dynamicreports.report.builder.style.StyleBuilder; 22 | import software.xdev.dynamicreports.report.builder.style.Styles; 23 | import software.xdev.dynamicreports.report.constant.HorizontalTextAlignment; 24 | 25 | 26 | public interface JasperGridReportStyles 27 | { 28 | StyleBuilder titleStyle(); 29 | 30 | StyleBuilder footerStyle(); 31 | 32 | StyleBuilder columnTitleStyle(); 33 | 34 | StyleBuilder columnStyle(); 35 | 36 | SimpleStyleBuilder columnStyleHighlighted(); 37 | 38 | class Default implements JasperGridReportStyles 39 | { 40 | protected final StyleBuilder defaultStyle = Styles.style().setPadding(2); 41 | protected final StyleBuilder boldCenterStyle = Styles.style(this.defaultStyle) 42 | .bold() 43 | .setHorizontalTextAlignment(HorizontalTextAlignment.CENTER); 44 | protected final StyleBuilder columnTitle = Styles.style(this.boldCenterStyle) 45 | .setBorder(Styles.pen1Point()).setBackgroundColor(Color.LIGHT_GRAY); 46 | protected final StyleBuilder columnStyle = Styles.style(this.defaultStyle) 47 | .setBorder(Styles.pen1Point()); 48 | 49 | @SuppressWarnings("checkstyle:MagicNumber") 50 | protected final SimpleStyleBuilder columnStyleHighlighted = Styles.simpleStyle() 51 | .setPadding(2) 52 | .setBackgroundColor(new Color(222, 222, 222)) // Extra light gray so that the data remains readable 53 | .setBorder(Styles.pen1Point()); 54 | 55 | @Override 56 | public StyleBuilder titleStyle() 57 | { 58 | return this.boldCenterStyle; 59 | } 60 | 61 | @Override 62 | public StyleBuilder footerStyle() 63 | { 64 | return this.boldCenterStyle; 65 | } 66 | 67 | @Override 68 | public StyleBuilder columnTitleStyle() 69 | { 70 | return this.columnTitle; 71 | } 72 | 73 | @Override 74 | public StyleBuilder columnStyle() 75 | { 76 | return this.columnStyle; 77 | } 78 | 79 | @Override 80 | public SimpleStyleBuilder columnStyleHighlighted() 81 | { 82 | return this.columnStyleHighlighted; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/test/java/software/xdev/vaadin/grid_exporter/grid/GridDataExtractorReflectionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.grid; 17 | 18 | import java.util.function.Function; 19 | import java.util.stream.Stream; 20 | 21 | import org.junit.jupiter.api.Assertions; 22 | import org.junit.jupiter.api.DisplayName; 23 | import org.junit.jupiter.params.ParameterizedTest; 24 | import org.junit.jupiter.params.provider.Arguments; 25 | import org.junit.jupiter.params.provider.MethodSource; 26 | 27 | import com.vaadin.flow.component.grid.ColumnPathRenderer; 28 | import com.vaadin.flow.component.grid.Grid; 29 | import com.vaadin.flow.data.renderer.TextRenderer; 30 | 31 | 32 | class GridDataExtractorReflectionTest 33 | { 34 | 35 | static Stream checkFormattedValue() 36 | { 37 | return Stream.of( 38 | new CheckFormattedValueTestData( 39 | "ValueProvider", 40 | gr -> gr.addColumn(DummyData::text)), 41 | new CheckFormattedValueTestData( 42 | "TextRenderer", 43 | gr -> gr.addColumn(new TextRenderer<>(DummyData::text))), 44 | new CheckFormattedValueTestData( 45 | "ColumnPathRenderer", 46 | gr -> gr.addColumn(new ColumnPathRenderer<>("text", DummyData::text))) 47 | ).map(td -> Arguments.of(td.testDesc(), td.columnCreator(), td.item(), td.expectedResult())); 48 | } 49 | 50 | @DisplayName("Checking formattedValue") 51 | @ParameterizedTest(name = "{displayName} with {0}") 52 | @MethodSource 53 | void checkFormattedValue( 54 | final String checkingDesc, 55 | final Function, Grid.Column> columnCreator, 56 | final DummyData item, 57 | final String expectedResult) 58 | { 59 | final Grid grid = new Grid<>(); 60 | 61 | final Grid.Column column = columnCreator.apply(grid); 62 | 63 | final String value = 64 | Assertions.assertDoesNotThrow(() -> new GridDataExtractor<>(grid).getFormattedValue(column, item)); 65 | 66 | Assertions.assertEquals(expectedResult, value); 67 | } 68 | 69 | record CheckFormattedValueTestData( 70 | String testDesc, 71 | Function, Grid.Column> columnCreator, 72 | DummyData item, 73 | String expectedResult 74 | ) 75 | { 76 | CheckFormattedValueTestData( 77 | final String testDesc, 78 | final Function, Grid.Column> columnCreator) 79 | { 80 | this(testDesc, columnCreator, new DummyData("Test"), "Test"); 81 | } 82 | } 83 | 84 | 85 | record DummyData(String text) 86 | { 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/format/AbstractFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.format; 17 | 18 | import java.util.ArrayList; 19 | import java.util.Arrays; 20 | import java.util.List; 21 | import java.util.Objects; 22 | import java.util.Optional; 23 | import java.util.function.Function; 24 | 25 | import software.xdev.vaadin.grid_exporter.Translator; 26 | 27 | 28 | public abstract class AbstractFormat implements Format 29 | { 30 | protected final String nameToDisplay; 31 | protected final String fileSuffix; 32 | protected final String mimeType; 33 | protected List>> configComponents = 34 | new ArrayList<>(); 35 | 36 | protected AbstractFormat( 37 | final String nameToDisplay, 38 | final String fileSuffix, 39 | final String mimeType) 40 | { 41 | this.nameToDisplay = Objects.requireNonNull(nameToDisplay); 42 | this.fileSuffix = Objects.requireNonNull(fileSuffix); 43 | this.mimeType = Objects.requireNonNull(mimeType); 44 | } 45 | 46 | @SafeVarargs 47 | public final void withConfigComponents( 48 | final Function>... configComponents) 49 | { 50 | this.configComponents.addAll(Arrays.asList(configComponents)); 51 | } 52 | 53 | @Override 54 | public String getFormatNameToDisplay() 55 | { 56 | return this.nameToDisplay; 57 | } 58 | 59 | @Override 60 | public String getFormatFilenameSuffix() 61 | { 62 | return this.fileSuffix; 63 | } 64 | 65 | @Override 66 | public String getMimeType() 67 | { 68 | return this.mimeType; 69 | } 70 | 71 | @Override 72 | public List>> getConfigComponents() 73 | { 74 | return this.configComponents; 75 | } 76 | 77 | protected Optional getConfigFrom( 78 | final List configs, 79 | final Class targetedConfigClass) 80 | { 81 | return configs.stream() 82 | .filter(targetedConfigClass::isInstance) 83 | .map(targetedConfigClass::cast) 84 | .findFirst(); 85 | } 86 | 87 | protected Optional getValueFrom( 88 | final List configs, 89 | final Class targetedConfigClass, 90 | final Function mapper) 91 | { 92 | return this.getConfigFrom(configs, targetedConfigClass) 93 | .stream() 94 | .findFirst() 95 | .map(mapper); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/format/SpecificConfigComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.format; 17 | 18 | import java.util.Objects; 19 | import java.util.function.Supplier; 20 | 21 | import com.vaadin.flow.component.Composite; 22 | import com.vaadin.flow.component.formlayout.FormLayout; 23 | import com.vaadin.flow.data.binder.Binder; 24 | 25 | import software.xdev.vaadin.grid_exporter.Translator; 26 | 27 | @SuppressWarnings("java:S1948") 28 | public abstract class SpecificConfigComponent 29 | extends Composite 30 | implements Translator 31 | { 32 | protected Translator translator; 33 | protected Supplier newConfigSupplier; 34 | protected String header; 35 | 36 | protected Binder binder = new Binder<>(); 37 | 38 | protected SpecificConfigComponent( 39 | final Translator translator, 40 | final Supplier newConfigSupplier, 41 | final String headerToTranslate) 42 | { 43 | this.setTranslator(translator); 44 | this.setNewConfigSupplier(newConfigSupplier); 45 | this.setHeaderAndTranslate(headerToTranslate); 46 | 47 | this.getContent().setResponsiveSteps( 48 | new FormLayout.ResponsiveStep("0", 1), 49 | new FormLayout.ResponsiveStep("400px", 2) 50 | ); 51 | } 52 | 53 | protected void setTranslator(final Translator translator) 54 | { 55 | this.translator = Objects.requireNonNull(translator); 56 | } 57 | 58 | protected void setNewConfigSupplier(final Supplier newConfigSupplier) 59 | { 60 | this.newConfigSupplier = Objects.requireNonNull(newConfigSupplier); 61 | } 62 | 63 | protected void setHeader(final String header) 64 | { 65 | this.header = header; 66 | } 67 | 68 | protected void setHeaderAndTranslate(final String headerToTranslate) 69 | { 70 | this.setHeader(this.translate(headerToTranslate)); 71 | } 72 | 73 | public Supplier getNewConfigSupplier() 74 | { 75 | return this.newConfigSupplier; 76 | } 77 | 78 | public String getHeader() 79 | { 80 | return this.header; 81 | } 82 | 83 | public void updateFrom(final T value) 84 | { 85 | this.binder.setBean(value); 86 | } 87 | 88 | public T getBean() 89 | { 90 | return this.binder.getBean(); 91 | } 92 | 93 | public boolean isValid() 94 | { 95 | return this.binder.isValid(); 96 | } 97 | 98 | @Override 99 | public String translate(final String key) 100 | { 101 | return this.translator != null ? this.translator.translate(key) : key; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 3.2.8 2 | * Updated dependencies 3 | 4 | # 3.2.7 5 | * Migrated deployment to _Sonatype Maven Central Portal_ [#155](https://github.com/xdev-software/standard-maven-template/issues/155) 6 | * Updated dependencies 7 | 8 | # 3.2.6 9 | * Fix naming so that Vaadin Directory sync works [#318](https://github.com/xdev-software/vaadin-addon-template/issues/318) 10 | * Updated dependencies 11 | 12 | # 3.2.5 13 | * Make it possible to better customize ``SpecificConfigComponent`` 14 | 15 | # 3.2.4 16 | * Updated dependencies 17 | 18 | # 3.2.3 19 | * Added dedicated method for adding steps to WizardPanel to make overriding it easier #269 20 | * Updated dependencies 21 | 22 | # 3.2.2 23 | * Fix column order being ignored #256 24 | 25 | # 3.2.1 26 | * Fix cells truncating data #229 27 | * Updated dependencies 28 | 29 | # 3.2.0 30 | * Updated to Vaadin 24.4 31 | 32 | # 3.1.0 33 | * Update to [JasperReports 7](https://github.com/xdev-software/dynamicreports-core-for-grid-exporter/blob/develop/CHANGELOG.md#200) 34 | * Updated dependencies 35 | 36 | # 3.0.3 37 | * ⚠️ GroupId changed from ``com.xdev-software`` to ``software.xdev`` 38 | * Updated dependencies 39 | 40 | # 3.0.2 41 | * Fixed not working translations on preview step #153 42 | * Updated dependencies 43 | 44 | # 3.0.1 45 | * Fixed compilation problems due to missing ``ecj`` dependency #98 46 | * Updated dependencies 47 | 48 | # 3.0.0 49 | ⚠️This release contains breaking changes 50 | 51 | * Adds support for Vaadin 24+, drops support for Vaadin 23
52 | If you are still using Vaadin 23, use the ``3.x`` versions. 53 | * Requires Java 17+ 54 | * Replaced the underlying reporting framework ``dynamicreports`` with [our fork of it](https://github.com/xdev-software/dynamicreports-core-for-grid-exporter) which is specially designed for this project 55 | * Differences from the original project are roughly described in the [changelog](https://github.com/xdev-software/dynamicreports-core-for-grid-exporter/blob/develop/CHANGELOG.md). 56 | * Removed ``XML`` from the default formats because the exported data was unusable 57 | * Replaced ``VaadinInternalRenderingColumnHeaderResolvingStrategy`` with ``VaadinColumnHeaderResolvingStrategy`` 58 | * Updated dependencies 59 | 60 | # 2.0.0 61 | * Undocked from RapidClipse 62 | * Changed package from ``com.rapidclipse.framework.server.reports`` to ``software.xdev.vaadin.grid_exporter`` 63 | * Restructured the UI 64 | * Using a step-by-step-wizard like layout 65 | * Made formats configurable via UI 66 | * Refactored software architecture to make the component more expandable 67 | * Removed ``XLS`` from default formats due to not included dependency which causes a crash (``XLSX`` still works) 68 | * Updated dependencies 69 | 70 | Example usage: 71 | 72 | | v1 | v2 | 73 | | --- | --- | 74 | | ``GridExportDialog.open(grid)`` | ``GridExporter.newWithDefaults(grid).open()`` | 75 | 76 | # 1.0.3 77 | * Removed unused code 78 | 79 | # 1.0.2 80 | * Updated dependencies 81 | * Vaadin 23.2 82 | 83 | # 1.0.1 84 | * Removed unnecessary code and dependencies; Updated jasperreports to latest version 85 | 86 | # 1.0.0 87 | Initial release 88 | 89 | * Forked project from the RapidClipse Framework (Version 11.0) 90 | * Updated to Vaadin 23 91 | * Removed unnecessary code and dependencies 92 | * Removed requirement that Grid columns need keys 93 | * Reworked localization - can now be explicitly set using ``GridExportLocalizationConfig`` 94 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | software.xdev 8 | vaadin-grid-exporter-root 9 | 3.2.9-SNAPSHOT 10 | pom 11 | 12 | 13 | XDEV Software 14 | https://xdev.software 15 | 16 | 17 | 18 | vaadin-grid-exporter 19 | vaadin-grid-exporter-demo 20 | 21 | 22 | 23 | UTF-8 24 | UTF-8 25 | 26 | 27 | 28 | 29 | Apache-2.0 30 | https://www.apache.org/licenses/LICENSE-2.0.txt 31 | repo 32 | 33 | 34 | 35 | 36 | 37 | checkstyle 38 | 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-checkstyle-plugin 43 | 3.6.0 44 | 45 | 46 | com.puppycrawl.tools 47 | checkstyle 48 | 12.1.0 49 | 50 | 51 | 52 | .config/checkstyle/checkstyle.xml 53 | true 54 | 55 | 56 | 57 | 58 | check 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | pmd 68 | 69 | 70 | 71 | org.apache.maven.plugins 72 | maven-pmd-plugin 73 | 3.28.0 74 | 75 | true 76 | true 77 | true 78 | 79 | .config/pmd/java/ruleset.xml 80 | 81 | 82 | 83 | 84 | net.sourceforge.pmd 85 | pmd-core 86 | 7.17.0 87 | 88 | 89 | net.sourceforge.pmd 90 | pmd-java 91 | 7.17.0 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | org.apache.maven.plugins 102 | maven-jxr-plugin 103 | 3.6.0 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/config/page/PageConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.config.page; 17 | 18 | import java.util.Arrays; 19 | import java.util.List; 20 | import java.util.Objects; 21 | 22 | import software.xdev.dynamicreports.report.constant.PageOrientation; 23 | import software.xdev.dynamicreports.report.constant.PageType; 24 | import software.xdev.vaadin.grid_exporter.format.SpecificConfig; 25 | 26 | 27 | public class PageConfig implements SpecificConfig 28 | { 29 | public static final int PAGE_MARGIN_MIN = 0; 30 | public static final int PAGE_MARGIN_MAX = 1_000; 31 | 32 | protected List availablePageTypes = Arrays.asList(PageType.values()); 33 | protected List availablePageOrientations = Arrays.asList(PageOrientation.values()); 34 | protected PageType selectedPageType = PageType.A4; 35 | protected PageOrientation selectedPageOrientation = PageOrientation.PORTRAIT; 36 | protected boolean usePageNumbering; 37 | protected int pageMargin = 20; 38 | 39 | public List getAvailablePageTypes() 40 | { 41 | return this.availablePageTypes; 42 | } 43 | 44 | public void setAvailablePageTypes(final List availablePageTypes) 45 | { 46 | this.availablePageTypes = Objects.requireNonNull(availablePageTypes); 47 | } 48 | 49 | public List getAvailablePageOrientations() 50 | { 51 | return this.availablePageOrientations; 52 | } 53 | 54 | public void setAvailablePageOrientations(final List availablePageOrientations) 55 | { 56 | this.availablePageOrientations = Objects.requireNonNull(availablePageOrientations); 57 | } 58 | 59 | public PageType getSelectedPageType() 60 | { 61 | return this.selectedPageType; 62 | } 63 | 64 | public void setSelectedPageType(final PageType selectedPageType) 65 | { 66 | this.selectedPageType = Objects.requireNonNull(selectedPageType); 67 | } 68 | 69 | public PageOrientation getSelectedPageOrientation() 70 | { 71 | return this.selectedPageOrientation; 72 | } 73 | 74 | public void setSelectedPageOrientation(final PageOrientation selectedPageOrientation) 75 | { 76 | this.selectedPageOrientation = Objects.requireNonNull(selectedPageOrientation); 77 | } 78 | 79 | public boolean isUsePageNumbering() 80 | { 81 | return this.usePageNumbering; 82 | } 83 | 84 | public void setUsePageNumbering(final boolean usePageNumbering) 85 | { 86 | this.usePageNumbering = usePageNumbering; 87 | } 88 | 89 | public int getPageMargin() 90 | { 91 | return this.pageMargin; 92 | } 93 | 94 | public void setPageMargin(final int pageMargin) 95 | { 96 | if(pageMargin < PAGE_MARGIN_MIN || pageMargin > PAGE_MARGIN_MAX) 97 | { 98 | throw new IllegalArgumentException("Invalid pageMargin value"); 99 | } 100 | this.pageMargin = pageMargin; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/wizard/GridExporterWizardState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.wizard; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | import java.util.Objects; 21 | 22 | import software.xdev.vaadin.grid_exporter.column.ColumnConfiguration; 23 | import software.xdev.vaadin.grid_exporter.components.wizard.WizardState; 24 | import software.xdev.vaadin.grid_exporter.format.Format; 25 | import software.xdev.vaadin.grid_exporter.format.SpecificConfig; 26 | import software.xdev.vaadin.grid_exporter.grid.GridDataExtractor; 27 | 28 | 29 | public class GridExporterWizardState implements WizardState 30 | { 31 | protected final GridDataExtractor gridDataExtractor; 32 | protected final List availableFormats; 33 | protected final List> availableColumns; 34 | 35 | protected String fileName = ""; 36 | protected List> selectedColumns; 37 | protected Format selectedFormat; 38 | 39 | protected final List specificConfigs = new ArrayList<>(); 40 | 41 | public GridExporterWizardState( 42 | final GridDataExtractor gridDataExtractor, 43 | final List availableFormats, 44 | final List> availableColumns) 45 | { 46 | this.gridDataExtractor = Objects.requireNonNull(gridDataExtractor); 47 | this.availableFormats = new ArrayList<>(Objects.requireNonNull(availableFormats)); 48 | this.availableColumns = new ArrayList<>(Objects.requireNonNull(availableColumns)); 49 | 50 | // By default, all columns should be selected that have a name 51 | this.selectedColumns = new ArrayList<>(availableColumns.stream() 52 | .filter(col -> !col.getHeader().isBlank()) 53 | .toList()); 54 | } 55 | 56 | public GridDataExtractor getGridDataExtractor() 57 | { 58 | return this.gridDataExtractor; 59 | } 60 | 61 | public List getAvailableFormats() 62 | { 63 | return this.availableFormats; 64 | } 65 | 66 | public List> getAvailableColumns() 67 | { 68 | return this.availableColumns; 69 | } 70 | 71 | public List> getSelectedColumns() 72 | { 73 | return this.selectedColumns; 74 | } 75 | 76 | public String getFileName() 77 | { 78 | return this.fileName; 79 | } 80 | 81 | public void setFileName(final String fileName) 82 | { 83 | this.fileName = Objects.requireNonNull(fileName); 84 | } 85 | 86 | public void setSelectedColumns(final List> selectedColumns) 87 | { 88 | this.selectedColumns = Objects.requireNonNull(selectedColumns); 89 | } 90 | 91 | public Format getSelectedFormat() 92 | { 93 | return this.selectedFormat; 94 | } 95 | 96 | public void setSelectedFormat(final Format selectedFormat) 97 | { 98 | this.selectedFormat = selectedFormat; 99 | } 100 | 101 | public List getSpecificConfigs() 102 | { 103 | return this.specificConfigs; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/test/java/software/xdev/vaadin/grid_exporter/column/headerresolving/VaadinColumnHeaderResolvingStrategyTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.column.headerresolving; 17 | 18 | import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; 19 | import static org.junit.jupiter.api.Assertions.assertEquals; 20 | import static org.junit.jupiter.api.Assertions.assertFalse; 21 | import static org.junit.jupiter.api.Assertions.assertTrue; 22 | 23 | import java.util.Optional; 24 | 25 | import org.junit.jupiter.api.DisplayName; 26 | import org.junit.jupiter.api.Test; 27 | 28 | import com.vaadin.flow.component.grid.Grid; 29 | import com.vaadin.flow.component.grid.Grid.Column; 30 | import com.vaadin.flow.component.html.Span; 31 | 32 | 33 | class VaadinColumnHeaderResolvingStrategyTest 34 | { 35 | @Test 36 | @DisplayName("Grid-Header is read correctly from a grid with one set column header") 37 | void checkSetHeaderText() 38 | { 39 | final String expectedHeader = "username"; 40 | 41 | final Grid grid = new Grid<>(); 42 | 43 | final Column colUsername = grid 44 | .addColumn(TestUserDTO::username) 45 | .setHeader(expectedHeader); 46 | 47 | final Optional optResolvedName = 48 | new VaadinColumnHeaderResolvingStrategy().resolve(colUsername); 49 | 50 | assertTrue(optResolvedName.isPresent(), "No resolved column name found"); 51 | assertEquals(expectedHeader, optResolvedName.get()); 52 | } 53 | 54 | @Test 55 | @DisplayName("Grid-Header be found when read from a grid with a column renderer/component") 56 | void checkSetHeaderComponent() 57 | { 58 | final String expectedHeader = "text"; 59 | 60 | final Grid grid = new Grid<>(); 61 | 62 | final Column colUsername = grid 63 | .addColumn(TestUserDTO::username) 64 | .setHeader(new Span(expectedHeader)); 65 | 66 | final Optional optResolvedName = 67 | new VaadinColumnHeaderResolvingStrategy().resolve(colUsername); 68 | 69 | assertTrue(optResolvedName.isPresent(), "No resolved column name found"); 70 | assertEquals(expectedHeader, optResolvedName.get()); 71 | } 72 | 73 | @Test 74 | @DisplayName("Grid-Header should not be found when read from a grid with no column header") 75 | void checkNoHeaderSet() 76 | { 77 | final Grid grid = new Grid<>(); 78 | 79 | final Column colUsername = grid 80 | .addColumn(TestUserDTO::username); 81 | 82 | final Optional optResolvedName = 83 | new VaadinColumnHeaderResolvingStrategy().resolve(colUsername); 84 | 85 | assertFalse(optResolvedName.isPresent(), "column name found"); 86 | } 87 | 88 | @Test 89 | @DisplayName("Test null safety") 90 | void nullSafety() 91 | { 92 | final Optional optResolvedName = 93 | assertDoesNotThrow( 94 | () -> new VaadinColumnHeaderResolvingStrategy().resolve(null)); 95 | 96 | assertFalse(optResolvedName.isPresent(), "column name found"); 97 | } 98 | 99 | record TestUserDTO(String username, String firstName, String lastName) 100 | { 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/jasper/config/page/PageConfigComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.jasper.config.page; 17 | 18 | import com.vaadin.flow.component.checkbox.Checkbox; 19 | import com.vaadin.flow.component.combobox.ComboBox; 20 | import com.vaadin.flow.component.textfield.IntegerField; 21 | 22 | import software.xdev.dynamicreports.report.constant.PageOrientation; 23 | import software.xdev.dynamicreports.report.constant.PageType; 24 | import software.xdev.vaadin.grid_exporter.Translator; 25 | import software.xdev.vaadin.grid_exporter.format.SpecificConfigComponent; 26 | import software.xdev.vaadin.grid_exporter.jasper.config.JasperConfigsLocalization; 27 | 28 | 29 | public class PageConfigComponent extends SpecificConfigComponent 30 | { 31 | protected final ComboBox cbPageType = new ComboBox<>(); 32 | protected final ComboBox cbPageOrientation = new ComboBox<>(); 33 | protected final Checkbox chbxPageNumbering = new Checkbox(); 34 | protected final IntegerField intfPageMargin = new IntegerField(); 35 | 36 | public PageConfigComponent(final Translator translator) 37 | { 38 | super(translator, PageConfig::new, JasperConfigsLocalization.PAGE); 39 | 40 | this.initUIs(); 41 | 42 | this.registerBindings(); 43 | } 44 | 45 | protected void initUIs() 46 | { 47 | this.cbPageType.setLabel(this.translate(JasperConfigsLocalization.FORMAT_PAGE_TYPE)); 48 | this.cbPageType.setItemLabelGenerator(PageType::name); 49 | 50 | this.cbPageOrientation.setLabel(this.translate(JasperConfigsLocalization.ORIENTATION)); 51 | this.cbPageOrientation.setItemLabelGenerator(po -> 52 | this.translate(JasperConfigsLocalization.ORIENTATION + "." + po.name().toLowerCase())); 53 | 54 | this.chbxPageNumbering.setLabel(this.translate(JasperConfigsLocalization.SHOW_PAGE_NUMBERS)); 55 | 56 | this.intfPageMargin.setLabel(this.translate(JasperConfigsLocalization.MARGIN)); 57 | this.intfPageMargin.setStepButtonsVisible(true); 58 | this.intfPageMargin.setMin(PageConfig.PAGE_MARGIN_MIN); 59 | this.intfPageMargin.setMax(PageConfig.PAGE_MARGIN_MAX); 60 | 61 | this.getContent().add(this.cbPageType, this.cbPageOrientation, this.chbxPageNumbering, this.intfPageMargin); 62 | } 63 | 64 | protected void registerBindings() 65 | { 66 | this.binder.forField(this.cbPageType) 67 | .asRequired() 68 | .bind(PageConfig::getSelectedPageType, PageConfig::setSelectedPageType); 69 | 70 | this.binder.forField(this.cbPageOrientation) 71 | .asRequired() 72 | .bind(PageConfig::getSelectedPageOrientation, PageConfig::setSelectedPageOrientation); 73 | 74 | this.binder.forField(this.chbxPageNumbering) 75 | .bind(PageConfig::isUsePageNumbering, PageConfig::setUsePageNumbering); 76 | 77 | this.binder.forField(this.intfPageMargin) 78 | .asRequired() 79 | .bind(PageConfig::getPageMargin, PageConfig::setPageMargin); 80 | } 81 | 82 | @Override 83 | public void updateFrom(final PageConfig value) 84 | { 85 | this.cbPageType.setItems(value.getAvailablePageTypes()); 86 | 87 | this.cbPageOrientation.setItems(value.getAvailablePageOrientations()); 88 | 89 | super.updateFrom(value); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/wizard/steps/PreviewStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.wizard.steps; 17 | 18 | import java.io.ByteArrayInputStream; 19 | import java.util.Objects; 20 | 21 | import com.vaadin.flow.component.ComponentEvent; 22 | import com.vaadin.flow.component.ComponentEventListener; 23 | import com.vaadin.flow.component.html.HtmlObject; 24 | import com.vaadin.flow.component.orderedlayout.VerticalLayout; 25 | import com.vaadin.flow.server.StreamResource; 26 | import com.vaadin.flow.shared.Registration; 27 | 28 | import software.xdev.vaadin.grid_exporter.GridExportLocalizationConfig; 29 | import software.xdev.vaadin.grid_exporter.Translator; 30 | import software.xdev.vaadin.grid_exporter.format.Format; 31 | import software.xdev.vaadin.grid_exporter.wizard.GridExporterWizardState; 32 | 33 | 34 | public class PreviewStep extends AbstractGridExportWizardStepComposite 35 | { 36 | protected HtmlObject resViewer = new HtmlObject(); 37 | 38 | public PreviewStep(final Translator translator) 39 | { 40 | super(translator); 41 | this.setStepName(this.translate(GridExportLocalizationConfig.PREVIEW)); 42 | 43 | this.initUI(); 44 | } 45 | 46 | protected void initUI() 47 | { 48 | this.resViewer.getStyle().set("text-align", "center"); 49 | this.resViewer.getElement().setText(this.translate(GridExportLocalizationConfig.UNABLE_TO_SHOW_PREVIEW)); 50 | this.resViewer.setSizeFull(); 51 | 52 | this.getContent().add(this.resViewer); 53 | this.getContent().setPadding(false); 54 | this.getContent().setSizeFull(); 55 | } 56 | 57 | @Override 58 | public void onEnterStep(final GridExporterWizardState state) 59 | { 60 | // Generate data and preview 61 | final Format format = state.getSelectedFormat(); 62 | final byte[] bytes = format.export( 63 | state.getGridDataExtractor(), 64 | state.getSelectedColumns(), 65 | state.getSpecificConfigs()); 66 | 67 | final StreamResource resource = new StreamResource( 68 | state.getFileName() + "." + format.getFormatFilenameSuffix(), 69 | () -> new ByteArrayInputStream(bytes) 70 | ); 71 | resource.setContentType(format.getMimeType()); 72 | 73 | this.resViewer.setType(format.getMimeType()); 74 | this.resViewer.setData(resource); 75 | 76 | this.fireEvent(new StreamResourceGeneratedEvent<>(resource, this, false)); 77 | } 78 | 79 | @SuppressWarnings({ "rawtypes", "unchecked"}) 80 | public Registration addStreamResourceGeneratedListener( 81 | final ComponentEventListener> listener) 82 | { 83 | return this.addListener(StreamResourceGeneratedEvent.class, (ComponentEventListener)listener); 84 | } 85 | 86 | public static class StreamResourceGeneratedEvent extends ComponentEvent> 87 | { 88 | protected final StreamResource resource; 89 | 90 | public StreamResourceGeneratedEvent( 91 | final StreamResource resource, 92 | final PreviewStep source, final boolean fromClient) 93 | { 94 | super(source, fromClient); 95 | this.resource = Objects.requireNonNull(resource); 96 | } 97 | 98 | public StreamResource getResource() 99 | { 100 | return this.resource; 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/column/ColumnConfigurationHeaderResolvingStrategyBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.column; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | import java.util.Map; 21 | import java.util.Optional; 22 | import java.util.function.Function; 23 | 24 | import com.vaadin.flow.component.grid.Grid.Column; 25 | import com.vaadin.flow.function.SerializableFunction; 26 | 27 | import software.xdev.vaadin.grid_exporter.column.headerresolving.ColumnHeaderResolvingStrategy; 28 | import software.xdev.vaadin.grid_exporter.column.headerresolving.ManualColumnHeaderResolvingStrategy; 29 | import software.xdev.vaadin.grid_exporter.column.headerresolving.VaadinColumnHeaderResolvingStrategy; 30 | 31 | 32 | /** 33 | * Builds a function (from multiple strategies) that resolves the text for a column.
If no strategies are specified 34 | * the fallback {@link Column#getKey()} is used. 35 | */ 36 | public class ColumnConfigurationHeaderResolvingStrategyBuilder 37 | { 38 | protected final List strategies = new ArrayList<>(); 39 | 40 | /** 41 | * Uses the {@link VaadinColumnHeaderResolvingStrategy} 42 | */ 43 | public ColumnConfigurationHeaderResolvingStrategyBuilder withVaadinInternalHeaderStrategy() 44 | { 45 | return this.withStrategy(new VaadinColumnHeaderResolvingStrategy()); 46 | } 47 | 48 | /** 49 | * Uses the {@link ManualColumnHeaderResolvingStrategy} 50 | */ 51 | public ColumnConfigurationHeaderResolvingStrategyBuilder withManualColumnHeaderStrategy( 52 | final Function, I> identifierResolver, 53 | final Map> headerTextResolverMap) 54 | { 55 | return this.withStrategy(new ManualColumnHeaderResolvingStrategy<>(identifierResolver, headerTextResolverMap)); 56 | } 57 | 58 | /** 59 | * Adds a new {@link ColumnHeaderResolvingStrategy}.
This strategy will be added at the end of the strategy 60 | * list. 61 | */ 62 | public ColumnConfigurationHeaderResolvingStrategyBuilder withStrategy(final ColumnHeaderResolvingStrategy strategy) 63 | { 64 | this.strategies.add(strategy); 65 | return this; 66 | } 67 | 68 | /** 69 | * Adds a new {@link ColumnHeaderResolvingStrategy}.
70 | * This strategy will be added at the start of the strategy list. 71 | */ 72 | public ColumnConfigurationHeaderResolvingStrategyBuilder 73 | withFirstStrategy(final ColumnHeaderResolvingStrategy strategy) 74 | { 75 | this.strategies.add(0, strategy); 76 | return this; 77 | } 78 | 79 | /** 80 | * Clears all existing strategies 81 | */ 82 | public ColumnConfigurationHeaderResolvingStrategyBuilder clearAllStrategies() 83 | { 84 | this.strategies.clear(); 85 | return this; 86 | } 87 | 88 | @SuppressWarnings("java:S1452") // Not exposed to the user and otherwise compilation failure 89 | public SerializableFunction, String> build() 90 | { 91 | return col -> 92 | { 93 | for(final ColumnHeaderResolvingStrategy resolvingFunction : this.strategies) 94 | { 95 | final Optional optResolvedValue = resolvingFunction.resolve(col); 96 | if(optResolvedValue.isPresent()) 97 | { 98 | return optResolvedValue.get(); 99 | } 100 | } 101 | 102 | // Fallback 103 | return col.getKey() != null ? col.getKey() : ""; 104 | }; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/GridExportLocalizationConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter; 17 | 18 | import static java.util.Map.entry; 19 | 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | import java.util.function.BiFunction; 23 | 24 | import com.vaadin.flow.component.Component; 25 | 26 | 27 | /** 28 | * Makes i18n possible for the component. As defaults the english language is used. 29 | */ 30 | public class GridExportLocalizationConfig 31 | { 32 | public static final String PREFIX = "gridexporter."; 33 | 34 | public static final String EXPORT_GRID = PREFIX + "export_grid"; 35 | 36 | public static final String CANCEL = PREFIX + "cancel"; 37 | public static final String PREVIOUS = PREFIX + "previous"; 38 | public static final String NEXT = PREFIX + "next"; 39 | public static final String DOWNLOAD = PREFIX + "download"; 40 | 41 | public static final String GENERAL = PREFIX + "general"; 42 | public static final String FILENAME = PREFIX + "filename"; 43 | public static final String COLUMNS = PREFIX + "columns"; 44 | public static final String NAME = PREFIX + "name"; 45 | public static final String POSITION = PREFIX + "position"; 46 | public static final String ALREADY_PRESENT = PREFIX + "already_present"; 47 | 48 | public static final String FORMAT = PREFIX + "format"; 49 | 50 | public static final String PREVIEW = PREFIX + "preview"; 51 | 52 | public static final String UNABLE_TO_SHOW_PREVIEW = PREFIX + "unable_to_show_preview"; 53 | 54 | // Key, Default Value 55 | public static final Map DEFAULT_VALUES = Map.ofEntries( 56 | entry(EXPORT_GRID, "Export Grid"), 57 | // Buttons 58 | entry(CANCEL, "Cancel"), 59 | entry(PREVIOUS, "Previous"), 60 | entry(NEXT, "Next"), 61 | entry(DOWNLOAD, "Download"), 62 | // Steps 63 | entry(GENERAL, "General"), 64 | entry(FILENAME, "Filename"), 65 | entry(COLUMNS, "Columns"), 66 | entry(NAME, "Name"), 67 | entry(POSITION, "Position"), 68 | entry(ALREADY_PRESENT, "Already present"), 69 | entry(FORMAT, "Format"), 70 | entry(PREVIEW, "Preview"), 71 | entry(UNABLE_TO_SHOW_PREVIEW, "Unable to show preview") 72 | ); 73 | 74 | // Key, Resolver 75 | protected final Map> keyResolvers = new HashMap<>(); 76 | 77 | public GridExportLocalizationConfig withAll(final Map keyValues) 78 | { 79 | keyValues.forEach(this::with); 80 | return this; 81 | } 82 | 83 | public GridExportLocalizationConfig with(final String key, final String value) 84 | { 85 | this.getKeyResolvers().put(key, (c, k) -> value); 86 | return this; 87 | } 88 | 89 | public GridExportLocalizationConfig withTranslation(final String key, final String i18nKey) 90 | { 91 | this.getKeyResolvers().put( 92 | key, 93 | (c, k) -> c.getTranslation(i18nKey)); 94 | return this; 95 | } 96 | 97 | public String getTranslation(final String key, final Component caller) 98 | { 99 | final BiFunction resolver = this.getKeyResolvers().get(key); 100 | if(resolver == null) 101 | { 102 | final String defaultValue = DEFAULT_VALUES.get(key); 103 | return defaultValue != null ? defaultValue : key; 104 | } 105 | return resolver.apply(caller, key); 106 | } 107 | 108 | public Map> getKeyResolvers() 109 | { 110 | return this.keyResolvers; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/grid/GridDataExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.grid; 17 | 18 | import java.lang.reflect.Field; 19 | import java.lang.reflect.InvocationTargetException; 20 | import java.lang.reflect.Method; 21 | import java.util.List; 22 | import java.util.Objects; 23 | import java.util.stream.Stream; 24 | 25 | import com.vaadin.flow.component.grid.ColumnPathRenderer; 26 | import com.vaadin.flow.component.grid.Grid; 27 | import com.vaadin.flow.data.provider.Query; 28 | import com.vaadin.flow.data.renderer.BasicRenderer; 29 | import com.vaadin.flow.data.renderer.Renderer; 30 | import com.vaadin.flow.function.ValueProvider; 31 | 32 | import software.xdev.vaadin.grid_exporter.column.ColumnConfiguration; 33 | 34 | 35 | /** 36 | * Extracts the sorted and filtered data from a {@link Grid}. 37 | *

38 | * Be aware that this class uses reflection to achieve it's goals. 39 | *

40 | */ 41 | @SuppressWarnings({"java:S3011", "unchecked"}) // Accessing non-public Vaadin fields 42 | public class GridDataExtractor 43 | { 44 | protected final Grid grid; 45 | 46 | public GridDataExtractor(final Grid grid) 47 | { 48 | this.grid = Objects.requireNonNull(grid); 49 | } 50 | 51 | public List> getSortedAndFilteredData(final List> columnsToExport) 52 | { 53 | return this.getSortedAndFilteredData(this.grid) 54 | .map(item -> columnsToExport.stream() 55 | .map(column -> this.getFormattedValue(column.getGridColumn(), item)) 56 | .toList()) 57 | .toList(); 58 | } 59 | 60 | protected String getFormattedValue(final Grid.Column column, final T item) 61 | { 62 | try 63 | { 64 | final Renderer renderer = column.getRenderer(); 65 | final ValueProvider valueProvider = this.getValueProvider(column); 66 | if(valueProvider != null) 67 | { 68 | final Method getValueFormatter = this.getValueFormatter(renderer); 69 | final Object value = valueProvider.apply(item); 70 | if(value != null && getValueFormatter != null) 71 | { 72 | return (String)getValueFormatter.invoke(renderer, value); 73 | } 74 | } 75 | else if(renderer instanceof ColumnPathRenderer) 76 | { 77 | final Field provider = ColumnPathRenderer.class.getDeclaredField("provider"); 78 | provider.setAccessible(true); 79 | final ValueProvider valprov = (ValueProvider)provider.get(renderer); 80 | if(valprov != null) 81 | { 82 | return valprov.apply(item).toString(); 83 | } 84 | } 85 | } 86 | catch(final IllegalAccessException | IllegalArgumentException | InvocationTargetException 87 | | NoSuchFieldException | SecurityException e) 88 | { 89 | // Something went wrong, but it's not our place to say what or why. 90 | } 91 | return null; 92 | } 93 | 94 | protected Method getValueFormatter(final R renderer) 95 | { 96 | for(final Method m : renderer.getClass().getDeclaredMethods()) 97 | { 98 | if("getFormattedValue".equals(m.getName())) 99 | { 100 | m.setAccessible(true); 101 | return m; 102 | } 103 | } 104 | return null; 105 | } 106 | 107 | protected ValueProvider getValueProvider(final Grid.Column column) 108 | { 109 | final Renderer r = column.getRenderer(); 110 | if(r instanceof BasicRenderer) 111 | { 112 | try 113 | { 114 | final Method getValueProvider = BasicRenderer.class.getDeclaredMethod("getValueProvider"); 115 | getValueProvider.setAccessible(true); 116 | return (ValueProvider)getValueProvider.invoke(r); 117 | } 118 | catch(final IllegalAccessException | IllegalArgumentException | InvocationTargetException 119 | | NoSuchMethodException | SecurityException e) 120 | { 121 | // Something went wrong, but it's not our place to say what or why. 122 | } 123 | } 124 | return null; 125 | } 126 | 127 | protected Stream getSortedAndFilteredData(final Grid grid) 128 | { 129 | return grid.getDataProvider().fetch( 130 | new Query<>( 131 | 0, 132 | Integer.MAX_VALUE, 133 | grid.getSortOrder().stream() 134 | .flatMap(so -> so.getSorted().getSortOrder(so.getDirection())) 135 | .toList(), 136 | grid.getDataCommunicator().getInMemorySorting(), 137 | null)); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Published on Vaadin Directory](https://img.shields.io/badge/Vaadin%20Directory-published-00b4f0?logo=vaadin)](https://vaadin.com/directory/component/gridexporter-for-vaadin) 2 | [![Latest version](https://img.shields.io/maven-central/v/software.xdev/vaadin-grid-exporter?logo=apache%20maven)](https://mvnrepository.com/artifact/software.xdev/vaadin-grid-exporter) 3 | [![Build](https://img.shields.io/github/actions/workflow/status/xdev-software/vaadin-grid-exporter/check-build.yml?branch=develop)](https://github.com/xdev-software/vaadin-grid-exporter/actions/workflows/check-build.yml?query=branch%3Adevelop) 4 | ![Vaadin 24+](https://img.shields.io/badge/Vaadin%20Platform/Flow-24+-00b4f0) 5 | 6 | # GridExporter for Vaadin 7 | 8 | The Vaadin Grid Exporter can convert nearly any Vaadin Grid to a variety of formats.
9 | This way you don't have to copy the Grid contents manually or print the whole website with the Grid. 10 | 11 | Out of the box supported formats: 12 | * CSV 13 | * Word (DOCX) 14 | * HTML 15 | * ODS 16 | * ODT 17 | * PDF 18 | * PowerPoint (PPTX) 19 | * RTF 20 | * Plain text 21 | * Excel (XLSX) 22 | 23 | _These formats are exported using [dynamicreports](https://github.com/xdev-software/dynamicreports-core-for-grid-exporter)._ 24 | 25 | It's also easy to extend the Exporter to support your custom format. 26 | 27 | ![demo](assets/preview.gif) 28 | 29 | > [!NOTE] 30 | >
Disclaimer about the scope of this component (click to expand) 31 | > 32 | > Although the GridExporter can handle most use-cases, extreme scenarios will likely impact performance, usability and might require some hacks.
33 | > For such cases custom written exports are recommended e.g. by utilizing JasperReports directly.
34 | > If you need help implementing these feel free to [contact us](#support) or open a [question](https://github.com/xdev-software/vaadin-grid-exporter/issues/new?assignees=&labels=question&projects=&template=question.yml) if you are not sure that the GridExporter is a good option for your scenario. 35 | > 36 | >
37 | 38 | ## Usage 39 | 40 | Default usage: 41 | 42 | ```java 43 | GridExporter 44 | .newWithDefaults(this.grExamples) 45 | .open(); 46 | ``` 47 | 48 | Custom format (see [JsonGridExporterProvider from Demo](vaadin-grid-exporter-demo/src/main/java/software/xdev/vaadin/gridexport/example/jsonext/JsonGridExporterProvider.java)): 49 | 50 | ```java 51 | GridExporter 52 | .newWithDefaults(this.grExamples) 53 | .loadFromProvider(new JsonGridExporterProvider()) 54 | .open(); 55 | ``` 56 | 57 | ## Installation 58 | 59 | [Installation guide for the latest release](https://github.com/xdev-software/vaadin-grid-exporter/releases/latest#Installation) 60 | 61 | ### Comaptibility with ``CSP`` (Content-Security-Policy) and ``X-Frame-Options`` 62 | 63 | > [!TIP] 64 | > In Spring Security the [default value of ``X-Frame-Options`` is ``DENY``](https://docs.spring.io/spring-security/reference/features/exploits/headers.html#headers-frame-options) which will break the preview if not changed. 65 | 66 | To show the preview the [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) or the [X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) (deprecated in favor of CSP) must be configured in a way that they allow showing same-site elements. 67 | 68 | This can be achieved by: 69 | * setting the CSP to include at least ``frame-ancestors 'self'`` and maybe additionally ``object-src 'self'`` 70 | * setting ``X-Frame-Options`` to ``SAMESITE``.
If you use Spring Security without a CSP the easiest way to set this is: 71 | ```java 72 | http.headers(c -> c.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)); 73 | ``` 74 | 75 | > [!NOTE] 76 | > Depending on the browser the settings sometimes have slightly different effects.
77 | > For example Firefox blocks the preview due to privacy reasons when ``X-Frame-Option=DENY`` and ``Content-Security-Policy=frame-ancestors 'self'; object-src 'self'; ...`` but Chrome does not. 78 | 79 | ### Compatibility with Vaadin 80 | 81 | | Vaadin version | GridExporter version | 82 | | --- | --- | 83 | | Vaadin 24+ (latest) | ``3+`` | 84 | | Vaadin 23 | ``2.x`` | 85 | 86 | ### Compatibility with JasperReports 87 | 88 | Starting with version [3.1.0](./CHANGELOG.md#310) JasperReports 7 is required. 89 | 90 | ### Spring-Boot 91 | * You may have to include ``software/xdev`` inside [``vaadin.allowed-packages``](https://vaadin.com/docs/latest/integrations/spring/configuration#configure-the-scanning-of-packages) 92 | 93 | ## Run the Demo 94 | * Checkout the repo 95 | * Run ``mvn install && mvn -f vaadin-grid-exporter-demo spring-boot:run`` 96 | * Open http://localhost:8080 97 | 98 |
99 | Show example 100 | 101 | ![demo](assets/demo.avif) 102 |
103 | 104 | ## Support 105 | If you need support as soon as possible and you can't wait for any pull request, feel free to use [our support](https://xdev.software/en/services/support). 106 | 107 | ## Contributing 108 | See the [contributing guide](./CONTRIBUTING.md) for detailed instructions on how to get started with our project. 109 | 110 | ## Dependencies and Licenses 111 | View the [license of the current project](LICENSE) or the [summary including all dependencies](https://xdev-software.github.io/vaadin-grid-exporter/dependencies) 112 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/wizard/GridExporterWizard.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.wizard; 17 | 18 | import java.util.Objects; 19 | 20 | import com.vaadin.flow.component.button.Button; 21 | import com.vaadin.flow.component.button.ButtonVariant; 22 | import com.vaadin.flow.component.dialog.Dialog; 23 | import com.vaadin.flow.component.icon.VaadinIcon; 24 | import com.vaadin.flow.router.AfterNavigationEvent; 25 | import com.vaadin.flow.router.AfterNavigationObserver; 26 | 27 | import software.xdev.vaadin.grid_exporter.GridExportLocalizationConfig; 28 | import software.xdev.vaadin.grid_exporter.Translator; 29 | import software.xdev.vaadin.grid_exporter.components.wizard.buttonbar.WizardButtonBarWithAnchor; 30 | import software.xdev.vaadin.grid_exporter.components.wizard.panel.WizardPanel; 31 | import software.xdev.vaadin.grid_exporter.wizard.steps.FormatStep; 32 | import software.xdev.vaadin.grid_exporter.wizard.steps.GeneralStep; 33 | import software.xdev.vaadin.grid_exporter.wizard.steps.PreviewStep; 34 | 35 | 36 | @SuppressWarnings("java:S1948") 37 | public class GridExporterWizard extends Dialog implements AfterNavigationObserver, Translator 38 | { 39 | protected final Button closeButton = new Button(VaadinIcon.CLOSE.create()); 40 | protected final WizardPanel> wizardPanel = new WizardPanel<>(); 41 | protected final WizardButtonBarWithAnchor buttonBar = new WizardButtonBarWithAnchor(this.wizardPanel); 42 | protected final PreviewStep previewStep; 43 | 44 | protected final GridExportLocalizationConfig localizationConfig; 45 | 46 | public GridExporterWizard( 47 | final GridExporterWizardState initialState, 48 | final GridExportLocalizationConfig localizationConfig) 49 | { 50 | this.localizationConfig = Objects.requireNonNull(localizationConfig); 51 | // Needs to be done after setting localizationConfig 52 | this.previewStep = new PreviewStep<>(this); 53 | 54 | this.initUI(); 55 | this.registerListeners(); 56 | 57 | this.wizardPanel.setState(initialState); 58 | } 59 | 60 | protected void initUI() 61 | { 62 | this.setHeaderTitle(this.translate(GridExportLocalizationConfig.EXPORT_GRID)); 63 | this.closeButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); 64 | this.getHeader().add(this.closeButton); 65 | 66 | this.addStepsToWizardPanel(); 67 | this.add(this.wizardPanel); 68 | 69 | this.buttonBar.withButtonText( 70 | WizardButtonBarWithAnchor::getBtnCancel, 71 | this.translate(GridExportLocalizationConfig.CANCEL)); 72 | this.buttonBar.withButtonText( 73 | WizardButtonBarWithAnchor::getBtnPrevious, 74 | this.translate(GridExportLocalizationConfig.PREVIOUS)); 75 | this.buttonBar.withButtonText( 76 | WizardButtonBarWithAnchor::getBtnNext, 77 | this.translate(GridExportLocalizationConfig.NEXT)); 78 | this.buttonBar.withButtonText( 79 | WizardButtonBarWithAnchor::getBtnDone, 80 | this.translate(GridExportLocalizationConfig.DOWNLOAD)); 81 | 82 | this.buttonBar.getAnchorDone().getElement().setAttribute("download", true); 83 | this.buttonBar.getBtnDone().setIcon(VaadinIcon.DOWNLOAD.create()); 84 | this.getFooter().add(this.buttonBar); 85 | 86 | this.setResizable(true); 87 | this.setDraggable(true); 88 | 89 | this.setWidth("80%"); 90 | this.setMaxWidth("70em"); 91 | 92 | this.setHeight("90%"); 93 | this.setMaxHeight("70em"); 94 | } 95 | 96 | protected void addStepsToWizardPanel() 97 | { 98 | this.wizardPanel.addStep(new GeneralStep<>(this)); 99 | this.wizardPanel.addStep(new FormatStep<>(this)); 100 | this.wizardPanel.addStep(this.previewStep); 101 | } 102 | 103 | protected void registerListeners() 104 | { 105 | this.closeButton.addClickListener(ev -> this.close()); 106 | 107 | this.buttonBar.addCancelClickListener(ev -> this.close()); 108 | 109 | // Add the StreamResource to the download button when the preview is shown 110 | this.previewStep.addStreamResourceGeneratedListener(ev -> 111 | this.buttonBar.getAnchorDone().setHref(ev.getResource())); 112 | // Free up StreamResource when the user leaves the preview (navigates back) 113 | this.wizardPanel.addStepStateChangedListener(ev -> { 114 | if(!ev.isLastStep() && !this.buttonBar.getAnchorDone().getHref().isBlank()) 115 | { 116 | this.buttonBar.getAnchorDone().setHref(""); 117 | } 118 | }); 119 | } 120 | 121 | @Override 122 | public void afterNavigation(final AfterNavigationEvent event) 123 | { 124 | // Workaround for https://github.com/vaadin/flow-components/issues/1541 125 | this.close(); 126 | } 127 | 128 | @Override 129 | public String translate(final String key) 130 | { 131 | return this.localizationConfig.getTranslation(key, this); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 99 | -------------------------------------------------------------------------------- /.github/workflows/check-build.yml: -------------------------------------------------------------------------------- 1 | name: Check Build 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: [ develop ] 7 | paths-ignore: 8 | - '**.md' 9 | - '.config/**' 10 | - '.github/**' 11 | - '.idea/**' 12 | - 'assets/**' 13 | pull_request: 14 | branches: [ develop ] 15 | paths-ignore: 16 | - '**.md' 17 | - '.config/**' 18 | - '.github/**' 19 | - '.idea/**' 20 | - 'assets/**' 21 | 22 | env: 23 | DEMO_MAVEN_MODULE: ${{ github.event.repository.name }}-demo 24 | 25 | jobs: 26 | build: 27 | runs-on: ubuntu-latest 28 | timeout-minutes: 30 29 | strategy: 30 | matrix: 31 | java: [17, 21, 25] 32 | distribution: [temurin] 33 | steps: 34 | - uses: actions/checkout@v5 35 | 36 | - name: Set up JDK 37 | uses: actions/setup-java@v5 38 | with: 39 | distribution: ${{ matrix.distribution }} 40 | java-version: ${{ matrix.java }} 41 | 42 | - name: Cache Maven 43 | uses: actions/cache@v4 44 | with: 45 | path: ~/.m2/repository 46 | key: ${{ runner.os }}-mvn-build-${{ hashFiles('**/pom.xml') }} 47 | restore-keys: | 48 | ${{ runner.os }}-mvn-build- 49 | 50 | - name: Cache Vaadin prod bundles 51 | uses: actions/cache@v4 52 | with: 53 | path: | 54 | **/bundles/prod.bundle 55 | key: ${{ runner.os }}-vaadin-prod-bundles-${{ hashFiles('**/pom.xml') }} 56 | restore-keys: | 57 | ${{ runner.os }}-vaadin-prod-bundles- 58 | 59 | - name: Build with Maven 60 | run: ./mvnw -B clean package 61 | 62 | - name: Check for uncommited changes 63 | run: | 64 | if [[ "$(git status --porcelain)" != "" ]]; then 65 | echo ---------------------------------------- 66 | echo git status 67 | echo ---------------------------------------- 68 | git status 69 | echo ---------------------------------------- 70 | echo git diff 71 | echo ---------------------------------------- 72 | git diff 73 | echo ---------------------------------------- 74 | echo Troubleshooting 75 | echo ---------------------------------------- 76 | echo "::error::Unstaged changes detected. Locally try running: git clean -ffdx && ./mvnw -B clean package -Pproduction" 77 | exit 1 78 | fi 79 | 80 | - name: Upload demo files 81 | uses: actions/upload-artifact@v4 82 | with: 83 | name: demo-files-java-${{ matrix.java }} 84 | path: ${{ env.DEMO_MAVEN_MODULE }}/target/${{ env.DEMO_MAVEN_MODULE }}.jar 85 | if-no-files-found: error 86 | 87 | checkstyle: 88 | runs-on: ubuntu-latest 89 | if: ${{ github.event_name != 'pull_request' || !startsWith(github.head_ref, 'renovate/') }} 90 | timeout-minutes: 15 91 | strategy: 92 | matrix: 93 | java: [17] 94 | distribution: [temurin] 95 | steps: 96 | - uses: actions/checkout@v5 97 | 98 | - name: Set up JDK 99 | uses: actions/setup-java@v5 100 | with: 101 | distribution: ${{ matrix.distribution }} 102 | java-version: ${{ matrix.java }} 103 | 104 | - name: Cache Maven 105 | uses: actions/cache@v4 106 | with: 107 | path: ~/.m2/repository 108 | key: ${{ runner.os }}-mvn-checkstyle-${{ hashFiles('**/pom.xml') }} 109 | restore-keys: | 110 | ${{ runner.os }}-mvn-checkstyle- 111 | 112 | - name: CheckStyle Cache 113 | uses: actions/cache@v4 114 | with: 115 | path: '**/target/checkstyle-cachefile' 116 | key: ${{ runner.os }}-checkstyle-${{ hashFiles('**/pom.xml') }} 117 | restore-keys: | 118 | ${{ runner.os }}-checkstyle- 119 | 120 | - name: Run Checkstyle 121 | run: ./mvnw -B checkstyle:check -P checkstyle -T2C 122 | 123 | pmd: 124 | runs-on: ubuntu-latest 125 | if: ${{ github.event_name != 'pull_request' || !startsWith(github.head_ref, 'renovate/') }} 126 | timeout-minutes: 15 127 | strategy: 128 | matrix: 129 | java: [17] 130 | distribution: [temurin] 131 | steps: 132 | - uses: actions/checkout@v5 133 | 134 | - name: Set up JDK 135 | uses: actions/setup-java@v5 136 | with: 137 | distribution: ${{ matrix.distribution }} 138 | java-version: ${{ matrix.java }} 139 | 140 | - name: Cache Maven 141 | uses: actions/cache@v4 142 | with: 143 | path: ~/.m2/repository 144 | key: ${{ runner.os }}-mvn-pmd-${{ hashFiles('**/pom.xml') }} 145 | restore-keys: | 146 | ${{ runner.os }}-mvn-pmd- 147 | 148 | - name: PMD Cache 149 | uses: actions/cache@v4 150 | with: 151 | path: '**/target/pmd/pmd.cache' 152 | key: ${{ runner.os }}-pmd-${{ hashFiles('**/pom.xml') }} 153 | restore-keys: | 154 | ${{ runner.os }}-pmd- 155 | 156 | - name: Run PMD 157 | run: ./mvnw -B test pmd:aggregate-pmd-no-fork pmd:check -P pmd -DskipTests -T2C 158 | 159 | - name: Run CPD (Copy Paste Detector) 160 | run: ./mvnw -B pmd:aggregate-cpd pmd:cpd-check -P pmd -DskipTests -T2C 161 | 162 | - name: Upload report 163 | if: always() 164 | uses: actions/upload-artifact@v4 165 | with: 166 | name: pmd-report 167 | if-no-files-found: ignore 168 | path: | 169 | target/reports/** 170 | -------------------------------------------------------------------------------- /vaadin-grid-exporter-demo/src/main/java/software/xdev/vaadin/gridexport/example/DemoView.java: -------------------------------------------------------------------------------- 1 | package software.xdev.vaadin.gridexport.example; 2 | 3 | import com.vaadin.flow.component.AttachEvent; 4 | import com.vaadin.flow.component.Composite; 5 | import com.vaadin.flow.component.button.Button; 6 | import com.vaadin.flow.component.grid.Grid; 7 | import com.vaadin.flow.component.grid.GridVariant; 8 | import com.vaadin.flow.component.icon.VaadinIcon; 9 | import com.vaadin.flow.component.orderedlayout.HorizontalLayout; 10 | import com.vaadin.flow.component.orderedlayout.VerticalLayout; 11 | import com.vaadin.flow.data.renderer.ComponentRenderer; 12 | import com.vaadin.flow.router.PageTitle; 13 | import com.vaadin.flow.router.Route; 14 | 15 | import software.xdev.vaadin.grid_exporter.GridExportLocalizationConfig; 16 | import software.xdev.vaadin.grid_exporter.GridExporter; 17 | import software.xdev.vaadin.grid_exporter.jasper.config.JasperConfigsLocalization; 18 | import software.xdev.vaadin.gridexport.example.jsonext.JsonGridExporterProvider; 19 | import software.xdev.vaadin.gridexport.example.pre_defined_title.PredefinedTitleProvider; 20 | 21 | 22 | @PageTitle("GridExport Examples") 23 | @Route("") 24 | public class DemoView extends Composite 25 | { 26 | private final Grid grExamples = new Grid<>(); 27 | 28 | public DemoView() 29 | { 30 | final HorizontalLayout hlButtonContainer = new HorizontalLayout(); 31 | hlButtonContainer.setPadding(false); 32 | hlButtonContainer.add( 33 | new Button( 34 | "Export", 35 | VaadinIcon.PRINT.create(), 36 | e -> GridExporter.newWithDefaults(this.grExamples) 37 | .open()), 38 | new Button( 39 | "Export (German translation)", 40 | VaadinIcon.PRINT.create(), 41 | e -> GridExporter.newWithDefaults(this.grExamples) 42 | .withLocalizationConfig(germanLocalizationConfig()) 43 | .open()), 44 | new Button( 45 | "Export (JSON)", 46 | VaadinIcon.PRINT.create(), 47 | e -> GridExporter.newWithDefaults(this.grExamples) 48 | .loadFromProvider(new JsonGridExporterProvider()) 49 | .open()), 50 | new Button( 51 | "Export (Predefined title)", 52 | VaadinIcon.PRINT.create(), 53 | e -> new GridExporter<>(this.grExamples) 54 | .loadFromProvider(new PredefinedTitleProvider("Custom title!")) 55 | .open()) 56 | ); 57 | 58 | this.grExamples 59 | .addColumn(Example::route) 60 | .setHeader("Route") 61 | .setFlexGrow(1); 62 | 63 | this.grExamples 64 | .addColumn(Example::name) 65 | .setHeader("Name") 66 | .setFlexGrow(1); 67 | 68 | this.grExamples 69 | .addColumn(Example::desc) 70 | .setHeader("Description") 71 | .setFlexGrow(1); 72 | 73 | this.grExamples 74 | .addColumn(new ComponentRenderer<>(x -> new Button("Dummy open button"))) 75 | .setAutoWidth(true) 76 | .setFlexGrow(0); 77 | 78 | this.grExamples.setSizeFull(); 79 | this.grExamples.addThemeVariants(GridVariant.LUMO_COMPACT); 80 | 81 | this.getContent().add( 82 | hlButtonContainer, 83 | this.grExamples); 84 | this.getContent().setHeightFull(); 85 | } 86 | 87 | @Override 88 | protected void onAttach(final AttachEvent attachEvent) 89 | { 90 | this.grExamples.setItems( 91 | new Example("styled", "Styled-Demo", "dark mode 🌑 and more"), 92 | new Example("parameter", "Parameter-Demo", "configuration is stored in QueryParameters"), 93 | new Example("localized", "Localized-Demo", "🌐 simple localization"), 94 | new Example("customized", "Customized-Demo", "usage of a customized DateRange") 95 | ); 96 | } 97 | 98 | record Example(String route, String name, String desc) 99 | { 100 | } 101 | 102 | static GridExportLocalizationConfig germanLocalizationConfig() 103 | { 104 | return new GridExportLocalizationConfig() 105 | .with(GridExportLocalizationConfig.EXPORT_GRID, "Tabelle exportieren") 106 | .with(GridExportLocalizationConfig.CANCEL, "Abbrechen") 107 | .with(GridExportLocalizationConfig.PREVIOUS, "Zurück") 108 | .with(GridExportLocalizationConfig.NEXT, "Weiter") 109 | .with(GridExportLocalizationConfig.DOWNLOAD, "Herunterladen") 110 | .with(GridExportLocalizationConfig.GENERAL, "Generell") 111 | .with(GridExportLocalizationConfig.FILENAME, "Dateiname") 112 | .with(GridExportLocalizationConfig.COLUMNS, "Spalten") 113 | .with(GridExportLocalizationConfig.NAME, "Name") 114 | .with(GridExportLocalizationConfig.POSITION, "Position") 115 | .with(GridExportLocalizationConfig.ALREADY_PRESENT, "Bereits vorhanden") 116 | .with(GridExportLocalizationConfig.FORMAT, "Format") 117 | .with(GridExportLocalizationConfig.PREVIEW, "Vorschau") 118 | .with(GridExportLocalizationConfig.UNABLE_TO_SHOW_PREVIEW, "Vorschau kann nicht angezeigt werden") 119 | .with(JasperConfigsLocalization.ENCODING, "Enkodierung") 120 | .with(JasperConfigsLocalization.WITH_BOM, "mit BOM") 121 | .with(JasperConfigsLocalization.HEADER, "Header") 122 | .with(JasperConfigsLocalization.EXPORT_HEADER, "Kopfzeilen exportieren") 123 | .with(JasperConfigsLocalization.HIGHLIGHTING, "Hervorhebungen") 124 | .with(JasperConfigsLocalization.HIGHLIGHT_ROWS, "Zeilen hervorheben") 125 | .with(JasperConfigsLocalization.PAGE, "Seite") 126 | .with(JasperConfigsLocalization.FORMAT_PAGE_TYPE, "Format / Seitentyp") 127 | .with(JasperConfigsLocalization.ORIENTATION, "Orientierung") 128 | .with(JasperConfigsLocalization.ORIENTATION_PORTRAIT, "Hochformat") 129 | .with(JasperConfigsLocalization.ORIENTATION_LANDSCAPE, "Querformat") 130 | .with(JasperConfigsLocalization.SHOW_PAGE_NUMBERS, "Seitennummerierung") 131 | .with(JasperConfigsLocalization.MARGIN, "Rand") 132 | .with(JasperConfigsLocalization.SEPARATOR, "Trennzeichen") 133 | .with(JasperConfigsLocalization.TITLE, "Titel"); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | We would absolutely love to get the community involved, and we welcome any form of contributions – comments and questions on different communication channels, issues and pull request and anything that you build and share using our components. 4 | 5 | ### Communication channels 6 | * Communication is primarily done using issues. 7 | * If you need support as soon as possible and you can't wait for any pull request, feel free to use [our support](https://xdev.software/en/services/support). 8 | * As a last resort measure or on otherwise important matter you may also [contact us directly](https://xdev.software/en/about-us/contact). 9 | 10 | ### Ways to help 11 | * **Report bugs**
Create an issue or send a pull request 12 | * **Send pull requests**
If you want to contribute code, check out the development instructions below. 13 | * However when contributing larger new features, please first discuss the change you wish to make via issue with the owners of this repository before making it.
Otherwise your work might be rejected and your effort was pointless. 14 | 15 | We also encourage you to read the [contribution instructions by GitHub](https://docs.github.com/en/get-started/quickstart/contributing-to-projects). 16 | 17 | ## Developing 18 | 19 | ### Software Requirements 20 | You should have the following things installed: 21 | * Git 22 | * Java 25 - should be as unmodified as possible (Recommended: [Eclipse Adoptium](https://adoptium.net/temurin/releases/)) 23 | * Maven (Note that the [Maven Wrapper](https://maven.apache.org/wrapper/) is shipped with the repo) 24 | 25 | ### Recommended setup 26 | * Install ``IntelliJ`` (Community Edition is sufficient) 27 | * Install the following plugins: 28 | * [Save Actions](https://plugins.jetbrains.com/plugin/22113) - Provides save actions, like running the formatter or adding ``final`` to fields 29 | * [SonarLint](https://plugins.jetbrains.com/plugin/7973-sonarlint) - CodeStyle/CodeAnalysis 30 | * You may consider disabling telemetry in the settings under ``Tools > Sonarlint -> About`` 31 | * [Checkstyle-IDEA](https://plugins.jetbrains.com/plugin/1065-checkstyle-idea) - CodeStyle/CodeAnalysis 32 | * Import the project 33 | * Ensure that everything is encoded in ``UTF-8`` 34 | * Ensure that the JDK/Java-Version is correct 35 | * To enable AUTOMATIC reloading/restarting while developing and running the app do this (further information in " 36 | SpringBoot-Devtools" section below; [Source](https://stackoverflow.com/q/33349456)): 37 | * ``Settings > Build, Execution, Deployment > Compiler``:
38 | Enable [``Build project automatically``](https://www.jetbrains.com/help/idea/compiling-applications.html#auto-build) 39 | * ``Settings > Advanced Settings``:
40 | Enable [``Allow auto-make to start even if developed application is currently running``](https://www.jetbrains.com/help/idea/advanced-settings.html#advanced_compiler) 41 | * To launch the Demo execute the predefined (launch) configuration ``Run Demo`` 42 | 43 | #### [SpringBoot-Developer-Tools](https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.devtools) 44 | ... should automatically be enabled.
45 | If you are changing a file and build the project, parts of the app get restarted.
46 | Bigger changes may require a complete restart. 47 | * [Vaadin automatically reloads the UI on each restart](https://vaadin.com/docs/latest/configuration/live-reload/spring-boot).
48 | You can control this behavior with the ``vaadin.devmode.liveReload.enabled`` property (default: ``true``). 49 | 50 | ## Releasing [![Build](https://img.shields.io/github/actions/workflow/status/xdev-software/vaadin-grid-exporter/release.yml?branch=master)](https://github.com/xdev-software/vaadin-grid-exporter/actions/workflows/release.yml) 51 | 52 | Before releasing: 53 | * Consider doing a [test-deployment](https://github.com/xdev-software/vaadin-grid-exporter/actions/workflows/test-deploy.yml?query=branch%3Adevelop) before actually releasing. 54 | * Check the [changelog](CHANGELOG.md) 55 | 56 | If the ``develop`` is ready for release, create a pull request to the ``master``-Branch and merge the changes 57 | 58 | When the release is finished do the following: 59 | * Merge the auto-generated PR (with the incremented version number) back into the ``develop`` 60 | * Ensure that [Vaadin Directory](https://vaadin.com/directory) syncs the update and maybe update the component / version there 61 | 62 | ### Release failures 63 | 64 | There are 2 modes of release failure: 65 | 1. The remote server was e.g. down and non of the artifacts got published 66 | 2. There was a build failure during release and only parts of the artifacts got released 67 | 68 | In case 1 we can re-release the existing version,
in case 2 we have to release a new version when we can't get the artifacts deleted (as is the case with Maven Central) 69 | 70 | #### How-to: Re-Releasing an existing version 71 | 72 | 1. Delete the release on GitHub 73 | 2. Delete the release Git tag from the repo (locally and remote!) 74 | 3. Delete the ``master``-Branch and re-create it from the ``develop`` branch (or reset it to the state before the release-workflow commits have been done) 75 | * This requires __temporarily__ removing the branch protection 76 | * Once this was done a new release is triggered immediately! 77 | 78 | #### How-to: Releasing a new version 79 | 80 | 1. Merge the ``master`` branch back into ``develop`` (or another temporary branch) 81 | 2. Make sure all master branch versions are prepared for a new release
e.g. if the broken release was ``1.0.0`` the version should now be at ``1.0.1-SNAPSHOT`` - the ``SNAPSHOT`` is important for the workflow! 82 | 3. Mark the broken release as broken e.g. inside the Changelog, GitHub Release page, etc.
83 | You can use something like this: 84 | ``` 85 | > [!WARNING] 86 | > This release is broken as my cat accidentally clicked the abort button during the process 87 | ``` 88 | 4. Merge the changes back into the ``master`` branch to trigger a new release 89 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/wizard/steps/FormatStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.wizard.steps; 17 | 18 | import java.util.Collections; 19 | import java.util.List; 20 | import java.util.Objects; 21 | 22 | import com.vaadin.flow.component.combobox.ComboBox; 23 | import com.vaadin.flow.component.details.Details; 24 | import com.vaadin.flow.component.details.DetailsVariant; 25 | import com.vaadin.flow.component.orderedlayout.VerticalLayout; 26 | import com.vaadin.flow.data.binder.Binder; 27 | import com.vaadin.flow.data.provider.DataProvider; 28 | 29 | import software.xdev.vaadin.grid_exporter.GridExportLocalizationConfig; 30 | import software.xdev.vaadin.grid_exporter.Translator; 31 | import software.xdev.vaadin.grid_exporter.format.Format; 32 | import software.xdev.vaadin.grid_exporter.format.SpecificConfig; 33 | import software.xdev.vaadin.grid_exporter.format.SpecificConfigComponent; 34 | import software.xdev.vaadin.grid_exporter.wizard.GridExporterWizardState; 35 | 36 | 37 | @SuppressWarnings("java:S1948") 38 | public class FormatStep extends AbstractGridExportWizardStepComposite 39 | { 40 | protected final Binder> binder = new Binder<>(); 41 | 42 | protected final ComboBox cbFormats = new ComboBox<>(); 43 | 44 | protected final VerticalLayout vlConfigs = new VerticalLayout(); 45 | 46 | protected List> configComponents = 47 | Collections.emptyList(); 48 | 49 | public FormatStep(final Translator translator) 50 | { 51 | super(translator); 52 | this.setStepName(this.translate(GridExportLocalizationConfig.FORMAT)); 53 | 54 | this.initUI(); 55 | 56 | this.registerListeners(); 57 | 58 | this.initBindings(); 59 | } 60 | 61 | protected void initUI() 62 | { 63 | this.cbFormats.setLabel(this.translate(GridExportLocalizationConfig.FORMAT)); 64 | this.cbFormats.setItemLabelGenerator(Format::getFormatNameToDisplay); 65 | this.cbFormats.setWidthFull(); 66 | this.cbFormats.setMaxWidth("16em"); 67 | 68 | this.vlConfigs.setSpacing(false); 69 | this.vlConfigs.setPadding(false); 70 | this.vlConfigs.setSizeFull(); 71 | 72 | this.getContent().add(this.cbFormats, this.vlConfigs); 73 | this.getContent().setPadding(false); 74 | this.getContent().setSizeFull(); 75 | } 76 | 77 | protected void registerListeners() 78 | { 79 | this.cbFormats.addValueChangeListener(ev -> 80 | { 81 | // Normally this should never happen due to the binder 82 | final Format newFormat = ev.getValue(); 83 | 84 | this.showConfigComponentsFor(newFormat); 85 | 86 | if(newFormat == null) 87 | { 88 | return; 89 | } 90 | 91 | this.bindConfigComponents(this.getWizardState(), true); 92 | }); 93 | } 94 | 95 | protected void showConfigComponentsFor(final Format format) 96 | { 97 | this.vlConfigs.removeAll(); 98 | 99 | this.configComponents = format != null 100 | ? format.getConfigComponents() 101 | .stream() 102 | .map(creator -> creator.apply(this)) 103 | .toList() 104 | : Collections.emptyList(); 105 | 106 | this.configComponents.forEach(c -> 107 | { 108 | final Details details = new Details(c.getHeader(), c); 109 | details.setOpened(true); 110 | details.addThemeVariants(DetailsVariant.FILLED, DetailsVariant.SMALL); 111 | details.setWidthFull(); 112 | 113 | this.vlConfigs.add(details); 114 | }); 115 | } 116 | 117 | @SuppressWarnings({"unchecked", "rawtypes"}) 118 | protected void bindConfigComponents( 119 | final GridExporterWizardState state, 120 | final boolean deleteNonMatchingFromState) 121 | { 122 | for(final SpecificConfigComponent component : this.configComponents) 123 | { 124 | final SpecificConfig newConfig = component.getNewConfigSupplier().get(); 125 | 126 | final SpecificConfig existing = state.getSpecificConfigs().stream() 127 | .filter(c -> Objects.equals(newConfig.getClass(), c.getClass())) 128 | .findFirst() 129 | .orElse(null); 130 | 131 | state.getSpecificConfigs().remove(existing); 132 | 133 | final SpecificConfig configToUse = existing == null ? newConfig : existing; 134 | 135 | ((SpecificConfigComponent)component).updateFrom(configToUse); 136 | 137 | state.getSpecificConfigs().add(configToUse); 138 | } 139 | 140 | if(deleteNonMatchingFromState) 141 | { 142 | // Remove all configs that are not required for the current state 143 | state.getSpecificConfigs().removeAll( 144 | state.getSpecificConfigs() 145 | .stream() 146 | .filter(ec -> this.configComponents.stream() 147 | .map(SpecificConfigComponent::getBean) 148 | .noneMatch(c -> Objects.equals(ec, c))) 149 | .toList() 150 | ); 151 | } 152 | } 153 | 154 | protected void initBindings() 155 | { 156 | this.binder.forField(this.cbFormats) 157 | .asRequired() 158 | .bind(GridExporterWizardState::getSelectedFormat, GridExporterWizardState::setSelectedFormat); 159 | } 160 | 161 | @Override 162 | public void onEnterStep(final GridExporterWizardState state) 163 | { 164 | this.cbFormats.setItems(DataProvider.ofCollection(state.getAvailableFormats())); 165 | 166 | this.binder.setBean(state); 167 | 168 | this.bindConfigComponents(state, false); 169 | } 170 | 171 | @Override 172 | public boolean onProgress(final GridExporterWizardState state) 173 | { 174 | return this.binder.isValid() && this.configComponents.stream().allMatch(SpecificConfigComponent::isValid); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /vaadin-grid-exporter/src/main/java/software/xdev/vaadin/grid_exporter/components/wizard/buttonbar/AbstractWizardButtonBar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2022 XDEV Software (https://xdev.software) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package software.xdev.vaadin.grid_exporter.components.wizard.buttonbar; 17 | 18 | import java.util.Objects; 19 | import java.util.function.Consumer; 20 | import java.util.function.Function; 21 | import java.util.stream.Stream; 22 | 23 | import com.vaadin.flow.component.Composite; 24 | import com.vaadin.flow.component.HasSize; 25 | import com.vaadin.flow.component.HasStyle; 26 | import com.vaadin.flow.component.button.Button; 27 | import com.vaadin.flow.component.button.ButtonVariant; 28 | import com.vaadin.flow.component.dependency.CssImport; 29 | import com.vaadin.flow.component.orderedlayout.FlexComponent; 30 | import com.vaadin.flow.component.orderedlayout.HorizontalLayout; 31 | import com.vaadin.flow.shared.Registration; 32 | 33 | import software.xdev.vaadin.grid_exporter.components.wizard.WizardStyles; 34 | import software.xdev.vaadin.grid_exporter.components.wizard.panel.WizardPanelActions; 35 | import software.xdev.vaadin.grid_exporter.components.wizard.step.WizardStepState; 36 | 37 | 38 | @CssImport(WizardStyles.LOCATION) 39 | public abstract class AbstractWizardButtonBar

> extends Composite 40 | implements HasSize, HasStyle 41 | { 42 | protected final Button btnCancel = new Button("Cancel"); 43 | protected final Button btnPrevious = new Button("Back"); 44 | protected final Button btnNext = new Button("Next"); 45 | protected final Button btnDone = new Button("Done"); 46 | 47 | protected final HorizontalLayout hlEndButtons = new HorizontalLayout(); 48 | 49 | protected void init(final WizardPanelActions panel) 50 | { 51 | Objects.requireNonNull(panel); 52 | 53 | this.initUI(); 54 | this.registerListeners(panel); 55 | 56 | // Set initial state 57 | this.updateFromStepState(new WizardStepState(0, 0)); 58 | } 59 | 60 | protected void initUI() 61 | { 62 | this.btnCancel.addClassName(WizardStyles.WIZARD_BUTTON_BAR_BTN_CANCEL); 63 | this.btnPrevious.addClassName(WizardStyles.WIZARD_BUTTON_BAR_BTN_PREVIOUS); 64 | this.btnNext.addClassName(WizardStyles.WIZARD_BUTTON_BAR_BTN_NEXT); 65 | this.btnDone.addClassName(WizardStyles.WIZARD_BUTTON_BAR_BTN_DONE); 66 | 67 | Stream.of(this.btnCancel, this.btnPrevious, this.btnNext, this.btnDone) 68 | .forEach(btn -> btn.setDisableOnClick(true)); 69 | 70 | Stream.of(this.btnNext, this.btnDone) 71 | .forEach(btn -> btn.addThemeVariants(ButtonVariant.LUMO_PRIMARY)); 72 | 73 | this.hlEndButtons.setPadding(false); 74 | this.hlEndButtons.add(this.btnPrevious, this.btnNext, this.btnDone); 75 | 76 | this.getContent().addClassName(WizardStyles.WIZARD_BUTTON_BAR); 77 | this.getContent().setPadding(false); 78 | this.getContent().setWidthFull(); 79 | this.getContent().setJustifyContentMode(FlexComponent.JustifyContentMode.BETWEEN); 80 | this.getContent().add(this.btnCancel, this.hlEndButtons); 81 | } 82 | 83 | protected void registerListeners(final WizardPanelActions panel) 84 | { 85 | this.addButtonClickEvent(this.getBtnPrevious(), panel::showPreviousStep); 86 | this.addButtonClickEvent(this.getBtnNext(), panel::showNextStep); 87 | 88 | panel.addStepStateChangedListener(this::updateFromStepState); 89 | } 90 | 91 | protected Registration addButtonClickEvent(final Button button, final Consumer isFromClientConsumer) 92 | { 93 | return button.addClickListener(ev -> 94 | { 95 | isFromClientConsumer.accept(ev.isFromClient()); 96 | ev.getSource().setEnabled(true); 97 | }); 98 | } 99 | 100 | protected void updateFromStepState(final WizardStepState stepState) 101 | { 102 | this.getBtnPrevious().setEnabled(!stepState.isFirstStep()); 103 | 104 | this.getBtnNext().setVisible(!stepState.isLastStep()); 105 | this.getBtnDone().setVisible(stepState.isLastStep()); 106 | } 107 | 108 | // region Getter for Buttons 109 | 110 | public Button getBtnCancel() 111 | { 112 | return this.btnCancel; 113 | } 114 | 115 | public Button getBtnPrevious() 116 | { 117 | return this.btnPrevious; 118 | } 119 | 120 | public Button getBtnNext() 121 | { 122 | return this.btnNext; 123 | } 124 | 125 | public Button getBtnDone() 126 | { 127 | return this.btnDone; 128 | } 129 | 130 | // endregion 131 | 132 | public P configureButton( 133 | final Function selfButtonSupplier, 134 | final Consumer