title: Not able to generate Excel file correctly using Spring Boot and Apache POI
body: <p>I have a very basic <code>SpringBoot</code> and <code>Thymeleaf</code> based application that is tied with <code>Oracle DB</code>.</p>
  
  <p>My application currently reads from a table and displays it on the page via a <code>Controller</code> and <code>Thymeleaf</code> UI template. I also have a link at the bottom of this table which says <code>"Export to Excel"</code> which calls a method in service layer and generates and even downloads that <code>.XLS</code> document successfully.</p>
  
  <p>However, the problem is that the excel getting generated is an exact replica of what is on the page (with some extra empty columns on the right) even though I have created the sheet manually by writing code which adds an extra column and a different title.</p>
  
  <p>Not sure why isn't my code getting invoked and why is my HTML table data just getting exported to the excel sheet as is.</p>
  
  <p><strong>ExcelReportController.java</strong></p>
  
  <pre><code>@Controller
  @Log4j2
  public class ExcelReportController {
  
      private static final String EXCEL_FILE_NAME = "applications.xls";
      @Autowired
      private LinkApplService linkApplService;
  
      @GetMapping("/excel")
      public ModelAndView showPage() {
          return new ModelAndView("applications", "linkAppls", linkApplService.getAllLinkAppls());
      }
  
      @GetMapping("/download")
      public ModelAndView download(HttpServletResponse response) {
          response.setHeader("Content-disposition", "attachment; filename=" + EXCEL_FILE_NAME);
          return new ModelAndView("applications", "linkAppls", linkApplService.getAllLinkAppls());
      }
  
  }
  </code></pre>
  
  <p><strong>ExcelBuilderService.java</strong></p>
  
  <pre><code>@Service
  public class ExcelBuilderService extends AbstractXlsView {
  
      @Override
      protected void buildExcelDocument(Map&lt;String, Object&gt; model, Workbook workbook, HttpServletRequest request,
                                        HttpServletResponse response) {
          Iterable&lt;LinkAppl&gt; linkAppls = (Iterable&lt;LinkAppl&gt;) model.get("linkAppls");
          //THIS SHEET WITH TITLE NOT GETTING SHOWN
          Sheet sheet = workbook.createSheet("All Applications List");
          Row header = sheet.createRow(0);
          header.createCell(0).setCellValue("ID");
          header.createCell(1).setCellValue("DESC");
          header.createCell(2).setCellValue("DESC");
          header.createCell(3).setCellValue("LINK_NOTES"); //THIS COLUMN NOT GETTING DISPLAYED
          int rowNum = 1;
          for (LinkAppl la : linkAppls) {
              Row row = sheet.createRow(rowNum++);
              row.createCell(0).setCellValue(la.getApplId());
              row.createCell(1).setCellValue(la.getApplDeTx());
              row.createCell(2).setCellValue(la.getApplActvCd());
              row.createCell(3).setCellValue(la.getLinkNotesTx());
          }
      }
  
  }
  </code></pre>
  
  <p><strong>LinkAppl.java</strong></p>
  
  <pre><code>@Entity
  @Table(name = "LINK_APPL")
  public class LinkAppl {
      private String applId;
      private String applDeTx;
      private String seqNbResetCd;
      private String intfMsgFrmtCd;
      private String sndRcvCd;
      private String applAcptMsgFrmtCd;
      private String applActvCd;
      private String sodEodIn;
      private String linkNotesTx;
      private String lastModByUsrId;
      private Timestamp lastModTs;
      private String sndCnctStsCd;
      private Long maxSeqNb;
      private String batIntfIn;
      private String gfpSrcSiteCd;
      private String rcvRterAckmentIn;
      private String rcvMqCodIn;
      private String fxApplIn;
      private String rcvEodpAckmentIn;
  
      //getters and setters go here
  
  }
  </code></pre>
  
  <p><strong>applications.html</strong></p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html xmlns:th="http://www.thymeleaf.org"&gt;
      &lt;head&gt;
          &lt;meta charset="utf-8"&gt;
          &lt;meta http-equiv="x-ua-compatible" content="ie=edge"&gt;
          &lt;title&gt;Link Statistics Report&lt;/title&gt;
          &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
      &lt;/head&gt;
      &lt;body&gt;
          &lt;h4&gt;Excel Generation Demo&lt;/h4&gt;
          &lt;table border="1"&gt;
              &lt;thead&gt;
                  &lt;tr&gt;
                      &lt;td&gt;App ID&lt;/td&gt;
                      &lt;td&gt;Name&lt;/td&gt;
                      &lt;td&gt;Active&lt;/td&gt;
                  &lt;/tr&gt;
              &lt;/thead&gt;
              &lt;tbody&gt;
                  &lt;tr th:each="a : ${linkAppls}"&gt;
                      &lt;td th:text="${a.applId}"&gt;App ID&lt;/td&gt;
                      &lt;td th:text="${a.getApplDeTx()}"&gt;Description&lt;/td&gt;
                      &lt;td th:text="${a.applActvCd}"&gt;Active&lt;/td&gt;
                  &lt;/tr&gt;
              &lt;/tbody&gt;
              &lt;tfoot&gt;
                  &lt;tr&gt;
                      &lt;td colspan="7"&gt;
                          &lt;a href="/download"&gt;Export to Excel&lt;/a&gt;
                      &lt;/td&gt;
                  &lt;/tr&gt;
              &lt;/tfoot&gt;
          &lt;/table&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p><strong>pom.xml</strong></p>
  
  <pre><code>&lt;!-- for handling .xls files (older format) --&gt;
  &lt;dependency&gt;
      &lt;groupId&gt;org.apache.poi&lt;/groupId&gt;
      &lt;artifactId&gt;poi&lt;/artifactId&gt;
      &lt;version&gt;4.0.1&lt;/version&gt;
  &lt;/dependency&gt;
  &lt;!-- for handling .xlsx files (newer format) --&gt;
  &lt;dependency&gt;
      &lt;groupId&gt;org.apache.poi&lt;/groupId&gt;
      &lt;artifactId&gt;poi-ooxml&lt;/artifactId&gt;
      &lt;version&gt;4.0.1&lt;/version&gt;
  &lt;/dependency&gt;
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/rbe9T.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/rbe9T.png" alt="enter image description here"></a></p>