2.3.6. Create a File Download Function

This section describes the function to download a CSV file, based on an example application.

Description of the function to be created
  1. Click the download button at the right side of the search results on the project list screen.
../../../../../_images/project_download-list.png
  1. The CSV file with the latest search results is downloaded.
../../../../../_images/project_download-download.png

2.3.6.1. Download the CSV file

How to implement the download function of the CSV file is explained.

For how to create project search function, refer to Create search function.

Create a download button

Configure a link that sends a GET request to the file download method.

/src/main/webapp/WEB-INF/view/project/index.jsp
<!-- Only the surrounding of the download button is described -->
<div style="float:left;">
    <span class="font-group">
    Search results
    </span>
    <span class="search-result-count">
        <c:if test="${not empty searchResult}">
            <n:write name="searchResult.pagination.resultCount" />
        </c:if>
        <c:if test="${empty searchResult}">
            0
        </c:if>
    </span>
    <!-- Configure the current search condition as a parameter -->
    <c:url value="/action/project/download" var="download_uri">
        <c:param name="searchForm.clientId" value="${searchForm.clientId}"/>
        <c:param name="searchForm.clientName" value="${searchForm.clientName}"/>
        <c:param name="searchForm.projectName" value="${searchForm.projectName}"/>
        <c:param name="searchForm.projectType" value="${searchForm.projectType}"/>
        <c:forEach items="${searchForm.projectClass}" var="projectClass">
            <c:param name="searchForm.projectClass" value="${projectClass}" />
        </c:forEach>
        <c:param name="searchForm.projectStartDateBegin" value="${searchForm.projectStartDateBegin}"/>
        <c:param name="searchForm.projectStartDateEnd" value="${searchForm.projectStartDateEnd}"/>
        <c:param name="searchForm.projectEndDateBegin" value="${searchForm.projectEndDateBegin}"/>
        <c:param name="searchForm.projectEndDateEnd" value="${searchForm.projectEndDateEnd}"/>
        <c:param name="searchForm.sortKey" value="${searchForm.sortKey}"/>
        <c:param name="searchForm.sortDir" value="${searchForm.sortDir}"/>
        <c:param name="searchForm.pageNumber" value="${searchForm.pageNumber}"/>
    </c:url>
    <n:a href="${download_uri}">
        <n:write name="label" />
        <n:img src="/images/download.png" alt="Download" />
    </n:a>
</div>
Create a Bean to bind a file

A bean to bind the contents of the file is created.

ProjectDownloadDto.java
@Csv(headers = { /** Describe the header **/},
        properties = { /** Properties to bind **/},
        type = Csv.CsvType.CUSTOM)
@CsvFormat(charset = "Shift_JIS", fieldSeparator = ',',ignoreEmptyLine = true,
        lineSeparator = "\r\n", quote = '"',
        quoteMode = CsvDataBindConfig.QuoteMode.NORMAL, requiredHeader = true, emptyToNull = true)
public class ProjectDownloadDto implements Serializable {

    // Excerpt of some items only. Getter and setter are omitted

    /** Project name */
    private String projectName;

    /** Project type */
    private String projectType;
}
Key points of this implementation
Create a business action method

Create a business action method to write the search results to a CSV file.

ProjectAction.java
@InjectForm(form = ProjectSearchForm.class, prefix = "searchForm", name = "searchForm")
@OnError(type = ApplicationException.class, path = "/WEB-INF/view/project/index.jsp")
public HttpResponse download(HttpRequest request, ExecutionContext context) {

    ProjectSearchForm searchForm = context.getRequestScopedVar("searchForm");
    ProjectSearchDto searchCondition = BeanUtil.createAndCopy(ProjectSearchDto.class, searchForm);
    LoginUserPrincipal userContext = SessionUtil.get(context, "userContext");
    searchCondition.setUserId(userContext.getUserId());

    final Path path = TempFileUtil.createTempFile();
    try (DeferredEntityList<ProjectDownloadDto> searchList = (DeferredEntityList<ProjectDownloadDto>) UniversalDao
            .defer()
            .findAllBySqlFile(ProjectDownloadDto.class, "SEARCH_PROJECT", searchCondition);
         ObjectMapper<ProjectDownloadDto> mapper = ObjectMapperFactory.create(ProjectDownloadDto.class,
                 TempFileUtil.newOutputStream(path))) {

        for (ProjectDownloadDto dto : searchList) {
            mapper.write(dto);
        }
    }

    FileResponse response = new FileResponse(path.toFile(), true);
    response.setContentType("text/csv; charset=Shift_JIS");
    response.setContentDisposition("Project List.csv");

    return response;
}
Key points of this implementation

This completes the description of the file download function.

Getting Started To TOP page