###SpringbootでCSVをダウンロードしてみます。日本語にも対応します。
####1.依存関係
build.gradle
dependencies {
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.webjars:jquery:3.3.1')
compile('com.fasterxml.jackson.dataformat:jackson-dataformat-csv');
runtime('org.springframework.boot:spring-boot-devtools')
compileOnly('org.projectlombok:lombok')
providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
jackson-dataformat-csvを使います
####2.Helper
ダウンロードするときに、ファイル名を日本語に対応するためのヘルパークラスを作成します。
DownloadHelper.java
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriUtils;
@Component
public class DownloadHelper {
private static final String CONTENT_DISPOSITION_FORMAT
= "attachment; filename=\"%s\"; filename*=UTF-8''%s";
public void addContentDisposition(HttpHeaders headers, String fileName)
throws UnsupportedEncodingException {
String headerValue = String.format(CONTENT_DISPOSITION_FORMAT,
fileName, UriUtils.encode(fileName, StandardCharsets.UTF_8.name()));
headers.add(HttpHeaders.CONTENT_DISPOSITION, headerValue);
}
}
####3.ダウンロードするデータ
Member.java
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import lombok.Data;
@JsonPropertyOrder({"ID", "名前", "プロフィール", "更新日時"})
@Data
public class Member {
@JsonProperty("ID")
private Long id;
@JsonProperty("名前")
private String name;
@JsonProperty("プロフィール")
private String desc;
@JsonProperty("更新日時")
@JsonFormat(pattern = "yyyy/MM/dd HH:mm:ss")
private Date modified;
public Member() {}
public Member(Long id, String name, String desc, Date modified) {
this.id = id;
this.name = name;
this.desc = desc;
this.modified = modified;
}
}
####4.Controller
CsvController.java
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.csv.CsvGenerator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
@Controller
public class CsvController {
@Autowired
DownloadHelper downloadHelper;
/**
* CsvMapperで、csvを作成する。
* @return csv(String)
* @throws JsonProcessingException
*/
public String getCsvText() throws JsonProcessingException {
CsvMapper mapper = new CsvMapper();
//文字列にダブルクオートをつける
mapper.configure(CsvGenerator.Feature.ALWAYS_QUOTE_STRINGS, true);
//ヘッダをつける
CsvSchema schema = mapper.schemaFor(Member.class).withHeader();
//メンバーデータをダウンロードするイメージ。本来はDBからデータを取得する。
List<Member> members = new ArrayList<Member>();
members.add(new Member(1L, "user01", "プロフィール1", new Date()));
members.add(new Member(2L, "user02", "プロフィール2", new Date()));
members.add(new Member(3L, "user03", "プロフィール3", new Date()));
return mapper.writer(schema).writeValueAsString(members);
}
/**
* csvをダウンロードする。
* @param response
* @return
* @throws IOException
*/
@RequestMapping(value = "/download/csv", method = RequestMethod.POST)
public ResponseEntity<byte[]> download() throws IOException {
HttpHeaders headers = new HttpHeaders();
downloadHelper.addContentDisposition(headers, "日本語ファイル名.csv");
return new ResponseEntity<>(getCsvText().getBytes("MS932"), headers, HttpStatus.OK);
}
}
####5.HTML
index.html
<!DOCTYPE html>
<html lang="ja" xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script th:src="@{/webjars/jquery/3.3.1/jquery.min.js}"></script>
</head>
<body>
<form id="csvform" method="post" th:action="@{/download/csv}">
<input type="hidden" name="filename"/>
<button type="submit">送信</button>
</form>
<script>
</script>
</body>
</html>
Postするだけのformです。
####6.確認
ダウンロードしたファイルの内容
日本語ファイル名.csv
"ID","名前","プロフィール","更新日時"
1,"user01","プロフィール1","2018/09/24 07:28:57"
2,"user02","プロフィール2","2018/09/24 07:28:57"
3,"user03","プロフィール3","2018/09/24 07:28:57"
ファイル名、ファイルの値ともに、日本語も問題なく出力できました。