├── .gitignore ├── README.md ├── pom.xml └── src ├── main ├── java │ └── me │ │ └── aboullaite │ │ ├── SpringBootExcelViewApplication.java │ │ ├── Utils.java │ │ ├── config │ │ └── WebConfig.java │ │ ├── controller │ │ ├── ExportController.java │ │ └── rest │ │ │ └── ApiController.java │ │ ├── model │ │ └── User.java │ │ ├── service │ │ └── UserService.java │ │ ├── view │ │ ├── AbstractCsvView.java │ │ ├── AbstractPdfView.java │ │ ├── CsvView.java │ │ ├── ExcelView.java │ │ └── PdfView.java │ │ └── viewResolver │ │ ├── CsvViewResolver.java │ │ ├── ExcelViewResolver.java │ │ └── PdfViewResolver.java └── resources │ └── application.yml └── test └── java └── me └── aboullaite └── SpringBootExcelViewApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | mvnw 4 | mvnw.cmd 5 | 6 | ### STS ### 7 | .apt_generated 8 | .classpath 9 | .factorypath 10 | .project 11 | .settings 12 | .springBeans 13 | 14 | ### IntelliJ IDEA ### 15 | .idea 16 | *.iws 17 | *.iml 18 | *.ipr 19 | 20 | ### NetBeans ### 21 | nbproject/private/ 22 | build/ 23 | nbbuild/ 24 | dist/ 25 | nbdist/ 26 | .nb-gradle/ 27 | .mvn/ 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spring Boot Export to Excel, CSV, and PDF. 2 | 3 | This is a very simple project that showcases export to Excel (using `AbstractXlsView`), CSV (by extending `AbstractView`) and PDF. 4 | 5 | This project favors file extensions (xls/csv/pdf) to resolve views. 6 | 7 | I'm using: 8 | 9 | - iText for PDF generation (AGPL license. From iText page: "As soon as you want to use iText in a closed source, proprietary environment, you have to purchase an iText commercial license of one of the types discussed above.") 10 | - Apache POI for Excel generation 11 | - Super CSV for CSV generation 12 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | me.aboullaite 7 | excel-view 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | Spring boot Excel view 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.1.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 34 | org.apache.poi 35 | poi 36 | 3.15 37 | 38 | 39 | 40 | org.apache.poi 41 | poi-ooxml 42 | 3.15 43 | 44 | 45 | 46 | net.sf.supercsv 47 | super-csv 48 | 2.4.0 49 | 50 | 51 | 52 | com.itextpdf 53 | itextpdf 54 | 5.5.10 55 | 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-starter-test 60 | test 61 | 62 | 63 | 64 | 65 | 66 | 67 | org.springframework.boot 68 | spring-boot-maven-plugin 69 | 70 | 71 | org.apache.maven.plugins 72 | maven-compiler-plugin 73 | 3.3 74 | 75 | 1.8 76 | 1.8 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/SpringBootExcelViewApplication.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringBootExcelViewApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringBootExcelViewApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/Utils.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import java.util.Random; 6 | 7 | @Component 8 | public class Utils { 9 | 10 | private final Random random; 11 | 12 | public Utils() { 13 | 14 | random = new Random(); 15 | } 16 | 17 | public String generateRandomChars(String pattern, int length) { 18 | 19 | StringBuilder sb = new StringBuilder(); 20 | 21 | 22 | return random.ints(0, pattern.length()) 23 | .mapToObj(pattern::charAt) 24 | .limit(length) 25 | .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) 26 | .toString(); 27 | } 28 | 29 | public Integer generateRandomInteger(Integer integer) { 30 | 31 | return random.ints(integer, 80) 32 | .findAny() 33 | .getAsInt(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/config/WebConfig.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite.config; 2 | 3 | import me.aboullaite.viewResolver.CsvViewResolver; 4 | import me.aboullaite.viewResolver.ExcelViewResolver; 5 | import me.aboullaite.viewResolver.PdfViewResolver; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.http.MediaType; 9 | import org.springframework.web.accept.ContentNegotiationManager; 10 | import org.springframework.web.servlet.ViewResolver; 11 | import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; 12 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 13 | import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | @Configuration 19 | public class WebConfig extends WebMvcConfigurerAdapter { 20 | 21 | @Override 22 | public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { 23 | configurer 24 | .defaultContentType(MediaType.APPLICATION_JSON) 25 | .favorPathExtension(true); 26 | } 27 | 28 | /* 29 | * Configure ContentNegotiatingViewResolver 30 | */ 31 | @Bean 32 | public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) { 33 | ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver(); 34 | resolver.setContentNegotiationManager(manager); 35 | 36 | // Define all possible view resolvers 37 | List resolvers = new ArrayList<>(); 38 | 39 | resolvers.add(csvViewResolver()); 40 | resolvers.add(excelViewResolver()); 41 | resolvers.add(pdfViewResolver()); 42 | 43 | resolver.setViewResolvers(resolvers); 44 | return resolver; 45 | } 46 | 47 | /* 48 | * Configure View resolver to provide XLS output using Apache POI library to 49 | * generate XLS output for an object content 50 | */ 51 | @Bean 52 | public ViewResolver excelViewResolver() { 53 | return new ExcelViewResolver(); 54 | } 55 | 56 | /* 57 | * Configure View resolver to provide Csv output using Super Csv library to 58 | * generate Csv output for an object content 59 | */ 60 | @Bean 61 | public ViewResolver csvViewResolver() { 62 | return new CsvViewResolver(); 63 | } 64 | 65 | /* 66 | * Configure View resolver to provide Pdf output using iText library to 67 | * generate pdf output for an object content 68 | */ 69 | @Bean 70 | public ViewResolver pdfViewResolver() { 71 | return new PdfViewResolver(); 72 | } 73 | 74 | 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/controller/ExportController.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite.controller; 2 | 3 | import me.aboullaite.service.UserService; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | 9 | @Controller 10 | public class ExportController { 11 | 12 | @Autowired 13 | private UserService userService; 14 | 15 | /** 16 | * Handle request to download an Excel document 17 | */ 18 | @GetMapping("/download") 19 | public String download(Model model) { 20 | 21 | model.addAttribute("users", userService.findAllUsers()); 22 | return ""; 23 | } 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/controller/rest/ApiController.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite.controller.rest; 2 | 3 | import me.aboullaite.model.User; 4 | import me.aboullaite.service.UserService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import java.util.List; 10 | 11 | @RestController 12 | public class ApiController { 13 | 14 | @Autowired 15 | private UserService userService; 16 | 17 | /** 18 | * Handle request to the default page 19 | */ 20 | @GetMapping("/") 21 | public List viewHome() { 22 | 23 | return userService.findAllUsers(); 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/model/User.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite.model; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | // In a real world app, this should be an Entity! 6 | @Component 7 | public class User { 8 | 9 | private String firstName; 10 | 11 | private String lastName; 12 | 13 | private Integer age; 14 | 15 | private String jobTitle; 16 | 17 | private String company; 18 | 19 | private String address; 20 | 21 | private String city; 22 | 23 | private String country; 24 | 25 | private String phoneNumber; 26 | 27 | public User() { 28 | 29 | } 30 | 31 | public User(String firstName, String lastName, Integer age, String jobTitle, String company, String address, 32 | String city, String country, String phoneNumber) { 33 | 34 | this.firstName = firstName; 35 | this.lastName = lastName; 36 | this.age = age; 37 | this.jobTitle = jobTitle; 38 | this.company = company; 39 | this.address = address; 40 | this.city = city; 41 | this.country = country; 42 | this.phoneNumber = phoneNumber; 43 | } 44 | 45 | public String getFirstName() { 46 | 47 | return firstName; 48 | } 49 | 50 | public void setFirstName(String firstName) { 51 | 52 | this.firstName = firstName; 53 | } 54 | 55 | public String getLastName() { 56 | 57 | return lastName; 58 | } 59 | 60 | public void setLastName(String lastName) { 61 | 62 | this.lastName = lastName; 63 | } 64 | 65 | public Integer getAge() { 66 | 67 | return age; 68 | } 69 | 70 | public void setAge(Integer age) { 71 | 72 | this.age = age; 73 | } 74 | 75 | public String getJobTitle() { 76 | 77 | return jobTitle; 78 | } 79 | 80 | public void setJobTitle(String jobTitle) { 81 | 82 | this.jobTitle = jobTitle; 83 | } 84 | 85 | public String getCompany() { 86 | 87 | return company; 88 | } 89 | 90 | public void setCompany(String company) { 91 | 92 | this.company = company; 93 | } 94 | 95 | public String getAddress() { 96 | 97 | return address; 98 | } 99 | 100 | public void setAddress(String address) { 101 | 102 | this.address = address; 103 | } 104 | 105 | public String getCity() { 106 | 107 | return city; 108 | } 109 | 110 | public void setCity(String city) { 111 | 112 | this.city = city; 113 | } 114 | 115 | public String getCountry() { 116 | 117 | return country; 118 | } 119 | 120 | public void setCountry(String country) { 121 | 122 | this.country = country; 123 | } 124 | 125 | public String getPhoneNumber() { 126 | 127 | return phoneNumber; 128 | } 129 | 130 | public void setPhoneNumber(String phoneNumber) { 131 | 132 | this.phoneNumber = phoneNumber; 133 | } 134 | 135 | public int getColumnCount() { 136 | 137 | return getClass().getDeclaredFields().length; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/service/UserService.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite.service; 2 | 3 | import me.aboullaite.Utils; 4 | import me.aboullaite.model.User; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | import java.util.stream.IntStream; 11 | 12 | @Service 13 | public class UserService { 14 | 15 | private final String candidateChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 16 | 17 | private final String candidateNum = "0123456789"; 18 | 19 | @Autowired 20 | private Utils appUtil; 21 | 22 | public List findAllUsers() { 23 | 24 | 25 | return IntStream.rangeClosed(1, 20) 26 | .mapToObj(i -> new User(appUtil.generateRandomChars(candidateChars, 10), appUtil.generateRandomChars 27 | (candidateChars, 10), appUtil.generateRandomInteger(i), 28 | appUtil.generateRandomChars(candidateChars, 15), appUtil.generateRandomChars(candidateChars, 29 | 15), appUtil.generateRandomChars(candidateChars, 20), 30 | appUtil.generateRandomChars(candidateChars, 10), appUtil.generateRandomChars(candidateChars, 31 | 10), appUtil.generateRandomChars(candidateNum, 10))) 32 | .collect(Collectors.toList()); 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/view/AbstractCsvView.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite.view; 2 | 3 | import org.springframework.web.servlet.view.AbstractView; 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | import javax.servlet.http.HttpServletResponse; 7 | import java.util.Map; 8 | 9 | public abstract class AbstractCsvView extends AbstractView { 10 | 11 | private static final String CONTENT_TYPE = "text/csv"; 12 | 13 | public AbstractCsvView() { 14 | setContentType(CONTENT_TYPE); 15 | } 16 | 17 | @Override 18 | protected boolean generatesDownloadContent() { 19 | return true; 20 | } 21 | 22 | 23 | @Override 24 | protected final void renderMergedOutputModel( 25 | Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { 26 | response.setContentType(getContentType()); 27 | buildCsvDocument(model, request, response); 28 | } 29 | 30 | protected abstract void buildCsvDocument( 31 | Map model, HttpServletRequest request, HttpServletResponse response) 32 | throws Exception; 33 | 34 | 35 | } -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/view/AbstractPdfView.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite.view; 2 | 3 | import com.itextpdf.text.Document; 4 | import com.itextpdf.text.DocumentException; 5 | import com.itextpdf.text.PageSize; 6 | import com.itextpdf.text.pdf.PdfWriter; 7 | import org.springframework.web.servlet.view.AbstractView; 8 | 9 | import javax.servlet.http.HttpServletRequest; 10 | import javax.servlet.http.HttpServletResponse; 11 | import java.io.ByteArrayOutputStream; 12 | import java.util.Map; 13 | 14 | public abstract class AbstractPdfView extends AbstractView { 15 | 16 | /** 17 | * This constructor sets the appropriate content type "application/pdf". 18 | * Note that IE won't take much notice of this, but there's not a lot we 19 | * can do about this. Generated documents should have a ".pdf" extension. 20 | */ 21 | public AbstractPdfView() { 22 | setContentType("application/pdf"); 23 | } 24 | 25 | @Override 26 | protected boolean generatesDownloadContent() { 27 | return true; 28 | } 29 | 30 | @Override 31 | protected final void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { 32 | 33 | // IE workaround: write into byte array first. 34 | ByteArrayOutputStream baos = createTemporaryOutputStream(); 35 | 36 | // Apply preferences and build metadata. 37 | Document document = new Document(PageSize.A4.rotate(), 36, 36, 54, 36); 38 | PdfWriter writer = PdfWriter.getInstance(document, baos); 39 | prepareWriter(model, writer, request); 40 | buildPdfMetadata(model, document, request); 41 | 42 | // Build PDF document. 43 | document.open(); 44 | buildPdfDocument(model, document, writer, request, response); 45 | document.close(); 46 | 47 | // Flush to HTTP response. 48 | writeToResponse(response, baos); 49 | } 50 | 51 | /** 52 | * Prepare the given PdfWriter. Called before building the PDF document, 53 | * that is, before the call to {@code Document.open()}. 54 | *

Useful for registering a page event listener, for example. 55 | * The default implementation sets the viewer preferences as returned 56 | * by this class's {@code getViewerPreferences()} method. 57 | * @param model the model, in case meta information must be populated from it 58 | * @param writer the PdfWriter to prepare 59 | * @param request in case we need locale etc. Shouldn't look at attributes. 60 | * @throws DocumentException if thrown during writer preparation 61 | */ 62 | protected void prepareWriter(Map model, PdfWriter writer, HttpServletRequest request) throws DocumentException { 63 | writer.setViewerPreferences(getViewerPreferences()); 64 | } 65 | 66 | /** 67 | * Return the viewer preferences for the PDF file. 68 | *

By default returns {@code AllowPrinting} and 69 | * {@code PageLayoutSinglePage}, but can be subclassed. 70 | * The subclass can either have fixed preferences or retrieve 71 | * them from bean properties defined on the View. 72 | * @return an int containing the bits information against PdfWriter definitions 73 | */ 74 | protected int getViewerPreferences() { 75 | return PdfWriter.ALLOW_PRINTING | PdfWriter.PageLayoutSinglePage; 76 | } 77 | 78 | /** 79 | * Populate the iText Document's meta fields (author, title, etc.). 80 | *
Default is an empty implementation. Subclasses may override this method 81 | * to add meta fields such as title, subject, author, creator, keywords, etc. 82 | * This method is called after assigning a PdfWriter to the Document and 83 | * before calling {@code document.open()}. 84 | * @param model the model, in case meta information must be populated from it 85 | * @param document the iText document being populated 86 | * @param request in case we need locale etc. Shouldn't look at attributes. 87 | */ 88 | protected void buildPdfMetadata(Map model, Document document, HttpServletRequest request) { 89 | } 90 | 91 | /** 92 | * Subclasses must implement this method to build an iText PDF document, 93 | * given the model. Called between {@code Document.open()} and 94 | * {@code Document.close()} calls. 95 | *

Note that the passed-in HTTP response is just supposed to be used 96 | * for setting cookies or other HTTP headers. The built PDF document itself 97 | * will automatically get written to the response after this method returns. 98 | * @param model the model Map 99 | * @param document the iText Document to add elements to 100 | * @param writer the PdfWriter to use 101 | * @param request in case we need locale etc. Shouldn't look at attributes. 102 | * @param response in case we need to set cookies. Shouldn't write to it. 103 | * @throws Exception any exception that occurred during document building 104 | */ 105 | protected abstract void buildPdfDocument(Map model, Document document, PdfWriter writer, 106 | HttpServletRequest request, HttpServletResponse response) throws Exception; 107 | } 108 | 109 | -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/view/CsvView.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite.view; 2 | 3 | import me.aboullaite.model.User; 4 | import org.supercsv.io.CsvBeanWriter; 5 | import org.supercsv.io.ICsvBeanWriter; 6 | import org.supercsv.prefs.CsvPreference; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public class CsvView extends AbstractCsvView { 14 | 15 | 16 | @Override 17 | protected void buildCsvDocument(Map model, HttpServletRequest request, HttpServletResponse 18 | response) throws Exception { 19 | 20 | response.setHeader("Content-Disposition", "attachment; filename=\"my-csv-file.csv\""); 21 | 22 | List users = (List) model.get("users"); 23 | String[] header = {"FirstName", "LastName", "LastName", "JobTitle", "Company", "Address", "City", "Country", 24 | "PhoneNumber"}; 25 | ICsvBeanWriter csvWriter = new CsvBeanWriter(response.getWriter(), 26 | CsvPreference.STANDARD_PREFERENCE); 27 | 28 | csvWriter.writeHeader(header); 29 | 30 | for (User user : users) { 31 | csvWriter.write(user, header); 32 | } 33 | csvWriter.close(); 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/view/ExcelView.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite.view; 2 | 3 | import me.aboullaite.model.User; 4 | import org.apache.poi.hssf.util.HSSFColor; 5 | import org.apache.poi.ss.usermodel.*; 6 | import org.springframework.web.servlet.view.document.AbstractXlsView; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public class ExcelView extends AbstractXlsView{ 14 | 15 | @Override 16 | protected void buildExcelDocument(Map model, 17 | Workbook workbook, 18 | HttpServletRequest request, 19 | HttpServletResponse response) throws Exception { 20 | 21 | // change the file name 22 | response.setHeader("Content-Disposition", "attachment; filename=\"my-xls-file.xls\""); 23 | 24 | @SuppressWarnings("unchecked") 25 | List users = (List) model.get("users"); 26 | 27 | // create excel xls sheet 28 | Sheet sheet = workbook.createSheet("User Detail"); 29 | sheet.setDefaultColumnWidth(30); 30 | 31 | // create style for header cells 32 | CellStyle style = workbook.createCellStyle(); 33 | Font font = workbook.createFont(); 34 | font.setFontName("Arial"); 35 | style.setFillForegroundColor(HSSFColor.BLUE.index); 36 | style.setFillPattern(FillPatternType.SOLID_FOREGROUND); 37 | font.setBold(true); 38 | font.setColor(HSSFColor.WHITE.index); 39 | style.setFont(font); 40 | 41 | 42 | // create header row 43 | Row header = sheet.createRow(0); 44 | header.createCell(0).setCellValue("FirstName"); 45 | header.getCell(0).setCellStyle(style); 46 | header.createCell(1).setCellValue("LastName"); 47 | header.getCell(1).setCellStyle(style); 48 | header.createCell(2).setCellValue("Age"); 49 | header.getCell(2).setCellStyle(style); 50 | header.createCell(3).setCellValue("Job Title"); 51 | header.getCell(3).setCellStyle(style); 52 | header.createCell(4).setCellValue("Company"); 53 | header.getCell(4).setCellStyle(style); 54 | header.createCell(5).setCellValue("Address"); 55 | header.getCell(5).setCellStyle(style); 56 | header.createCell(6).setCellValue("City"); 57 | header.getCell(6).setCellStyle(style); 58 | header.createCell(7).setCellValue("Country"); 59 | header.getCell(7).setCellStyle(style); 60 | header.createCell(8).setCellValue("Phone Number"); 61 | header.getCell(8).setCellStyle(style); 62 | 63 | 64 | 65 | int rowCount = 1; 66 | 67 | for(User user : users){ 68 | Row userRow = sheet.createRow(rowCount++); 69 | userRow.createCell(0).setCellValue(user.getFirstName()); 70 | userRow.createCell(1).setCellValue(user.getLastName()); 71 | userRow.createCell(2).setCellValue(user.getAge()); 72 | userRow.createCell(3).setCellValue(user.getJobTitle()); 73 | userRow.createCell(4).setCellValue(user.getCompany()); 74 | userRow.createCell(5).setCellValue(user.getAddress()); 75 | userRow.createCell(6).setCellValue(user.getCity()); 76 | userRow.createCell(7).setCellValue(user.getCountry()); 77 | userRow.createCell(8).setCellValue(user.getPhoneNumber()); 78 | 79 | } 80 | 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/view/PdfView.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite.view; 2 | 3 | import com.itextpdf.text.*; 4 | import com.itextpdf.text.pdf.PdfPCell; 5 | import com.itextpdf.text.pdf.PdfPTable; 6 | import com.itextpdf.text.pdf.PdfWriter; 7 | import me.aboullaite.model.User; 8 | import org.apache.poi.ss.usermodel.Row; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | import java.time.LocalDate; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | public class PdfView extends AbstractPdfView { 17 | @Override 18 | protected void buildPdfDocument(Map model, Document document, PdfWriter writer, HttpServletRequest request, HttpServletResponse response) throws Exception { 19 | // change the file name 20 | response.setHeader("Content-Disposition", "attachment; filename=\"my-pdf-file.pdf\""); 21 | 22 | List users = (List) model.get("users"); 23 | document.add(new Paragraph("Generated Users " + LocalDate.now())); 24 | 25 | PdfPTable table = new PdfPTable(users.stream().findAny().get().getColumnCount()); 26 | table.setWidthPercentage(100.0f); 27 | table.setSpacingBefore(10); 28 | 29 | // define font for table header row 30 | Font font = FontFactory.getFont(FontFactory.TIMES); 31 | font.setColor(BaseColor.WHITE); 32 | 33 | // define table header cell 34 | PdfPCell cell = new PdfPCell(); 35 | cell.setBackgroundColor(BaseColor.DARK_GRAY); 36 | cell.setPadding(5); 37 | 38 | // write table header 39 | cell.setPhrase(new Phrase("First Name", font)); 40 | table.addCell(cell); 41 | 42 | cell.setPhrase(new Phrase("Last Name", font)); 43 | table.addCell(cell); 44 | 45 | cell.setPhrase(new Phrase("Age", font)); 46 | table.addCell(cell); 47 | 48 | cell.setPhrase(new Phrase("Job Title", font)); 49 | table.addCell(cell); 50 | 51 | cell.setPhrase(new Phrase("Company", font)); 52 | table.addCell(cell); 53 | 54 | cell.setPhrase(new Phrase("Address", font)); 55 | table.addCell(cell); 56 | 57 | cell.setPhrase(new Phrase("City", font)); 58 | table.addCell(cell); 59 | 60 | cell.setPhrase(new Phrase("Country", font)); 61 | table.addCell(cell); 62 | 63 | cell.setPhrase(new Phrase("Phone Number", font)); 64 | table.addCell(cell); 65 | 66 | for(User user : users){ 67 | table.addCell(user.getFirstName()); 68 | table.addCell(user.getLastName()); 69 | table.addCell(user.getAge().toString()); 70 | table.addCell(user.getJobTitle()); 71 | table.addCell(user.getCompany()); 72 | table.addCell(user.getAddress()); 73 | table.addCell(user.getCity()); 74 | table.addCell(user.getCountry()); 75 | table.addCell(user.getPhoneNumber()); 76 | 77 | } 78 | 79 | document.add(table); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/viewResolver/CsvViewResolver.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite.viewResolver; 2 | 3 | import me.aboullaite.view.CsvView; 4 | import org.springframework.web.servlet.View; 5 | import org.springframework.web.servlet.ViewResolver; 6 | 7 | import java.util.Locale; 8 | 9 | public class CsvViewResolver implements ViewResolver { 10 | 11 | @Override 12 | public View resolveViewName(String s, Locale locale) throws Exception { 13 | 14 | return new CsvView(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/viewResolver/ExcelViewResolver.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite.viewResolver; 2 | 3 | import me.aboullaite.view.ExcelView; 4 | import org.springframework.web.servlet.View; 5 | import org.springframework.web.servlet.ViewResolver; 6 | 7 | import java.util.Locale; 8 | 9 | public class ExcelViewResolver implements ViewResolver { 10 | 11 | @Override 12 | public View resolveViewName(String s, Locale locale) throws Exception { 13 | 14 | return new ExcelView(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/me/aboullaite/viewResolver/PdfViewResolver.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite.viewResolver; 2 | 3 | import me.aboullaite.view.PdfView; 4 | import org.springframework.web.servlet.View; 5 | import org.springframework.web.servlet.ViewResolver; 6 | 7 | import java.util.Locale; 8 | 9 | public class PdfViewResolver implements ViewResolver { 10 | 11 | @Override 12 | public View resolveViewName(String s, Locale locale) throws Exception { 13 | 14 | return new PdfView(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aboullaite/SpringBoot-Excel-Csv/188e94efae9c57a128f5ff425e2081799d627523/src/main/resources/application.yml -------------------------------------------------------------------------------- /src/test/java/me/aboullaite/SpringBootExcelViewApplicationTests.java: -------------------------------------------------------------------------------- 1 | package me.aboullaite; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringBootExcelViewApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------