はじめに
SpringBootで商品テーブルからデータを検索し、TSVファイル出力してダウンロードするボタンを実装したい。
依存関係の追加
"jackson-dataformat-csv"を追加するとcsvの変換をやってくれるので簡単です。
```java`pom.xml
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-web
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-csv</artifactId>
</dependency>
# Modelの実装
Item.javaに対して@JsonProperty を設定する
@JsonProperty で設定した値が、1行目に出力されます。設定しない場合はフィールド名が自動で出力されます。
また、@JsonPropertyOrder を設定することで任意の順番で出力することができます。
```java
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonPropertyOrder({"id","name","condition","category","brand","price","shipping","description"})
public class Item {
@JsonProperty("id")
private Integer id;
@JsonProperty("name")
private String name;
@JsonProperty("condition")
private Integer condition;
@JsonProperty("category")
private Integer category;
@JsonProperty("brand")
private String brand;
@JsonProperty("price")
private Integer price;
@JsonProperty("shipping")
private Integer shipping;
@JsonProperty("description")
private String description;
///以下getter/setter
一部余計なフィールドがcsvに出力されてしまうみたいなので、
@JsonIgnore を設定し、そのフィールドを変換の対象外にする。
@JsonIgnore
private String nameAll;
フィールド変数"nameAll"は変換されなくなった。
Controllerクラスの実装
Object <-> CSV の変換に CsvMapper というクラスを使用して、オブジェクトを CSV に変換します。
また、出力するcharset は Shift_JIS を指定します。
また、ダウンロードされるファイルのデフォルトの名前は URL に準じるため、"*.tsv" という URL を割り当てておくだけで、リクエストされたファイル名でそのままダウンロードさせることが可能になります。
@Controller
@RequestMapping("tsv")
public class TsvController {
@Autowired
private ItemRepository itemRepository;
@GetMapping(value = "*.tsv",
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=Shift_JIS; Content-Disposition: attachment")
@ResponseBody
public Object getTsv() throws JsonProcessingException {
// DBから全件取得
List<Item> todos = itemRepository.findAll();
CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(Item.class).withHeader().withColumnSeparator('\t');
return mapper.writer(schema).writeValueAsString(todos);
}
}
ヘッダーありの場合は.withHeader()を付ける
csvをtsvに変換する場合は.withColumnSeparator('\t')を付ける
DLボタンの作成
<!-- tsv_downloadボタン -->
<form method="get" th:action="@{/tsv/demo.tsv}">
<input type="submit" name="download_file" value="ファイルをダウンロード">
</form>
リクエストするファイル名でDLをすることができる。
動作確認
無事tsv形式でDLができました。