Spring MVCでExcelファイルをアップロードして表示する
1前書き
この記事では、
Spring MVC
フレームワークを使用して
Excelファイルをアップロードしてその内容をWebページに表示する
方法を説明します。
2 Excelファイルのアップロード
ファイルをアップロードできるようにするために、まず
MultipartFile
を受け取り、それを現在の場所に保存するコントローラマッピングを作成します。
private String fileLocation;
@PostMapping("/uploadExcelFile")
public String uploadFile(Model model, MultipartFile file) throws IOException {
InputStream in = file.getInputStream();
File currDir = new File(".");
String path = currDir.getAbsolutePath();
fileLocation = path.substring(0, path.length() - 1) + file.getOriginalFilename();
FileOutputStream f = new FileOutputStream(fileLocation);
int ch = 0;
while ((ch = in.read()) != -1) {
f.write(ch);
}
f.flush();
f.close();
model.addAttribute("message", "File: " + file.getOriginalFilename()
+ " has been uploaded successfully!");
return "excel";
}
次に、
accept
属性がExcelファイルのみを許可するように設定される
input
of
type file
を含むフォームで
JSP
ファイルを作成しましょう。
<c:url value="/uploadExcelFile" var="uploadFileUrl"/>
<form method="post" enctype="multipart/form-data"
action="${uploadFileUrl}">
<input type="file" name="file" accept=".xls,.xlsx"/> <input
type="submit" value="Upload file"/>
</form>
3 Excelファイルの読み方
アップロードされたエクセルファイルを解析するために、我々は
Apache POI
ライブラリを使用します。これは
.xls
と
.xlsx
ファイルの両方で動作します。
コンテンツと書式設定に関連するExcelセルのプロパティを含む
MyCell
という名前のヘルパークラスを作成しましょう。
public class MyCell {
private String content;
private String textColor;
private String bgColor;
private String textSize;
private String textWeight;
public MyCell(String content) {
this.content = content;
}
//standard constructor, getters, setters
}
Excelファイルの内容を、
MyCell
オブジェクトのリストを含む
Map
に読み込みます。
3.1. .xlsファイルの解析
-
.xls
ファイルは、
HSSFSheet
オブジェクトで構成される
HSSFWorkbook
クラス** によって
Apache POI
ライブラリに表されます。
.xls
ファイルの内容を開いたり読んだりするには、
JavaでMicrosoft Excelを操作する
を参照してください。 -
セルのフォーマットを解析するために、
HSSFCellStyle
** オブジェクトを取得します。すべての読み取りプロパティは、
MyCell
オブジェクトの属性に設定されます。
HSSFCellStyle cellStyle = cell.getCellStyle();
MyCell myCell = new MyCell();
HSSFColor bgColor = cellStyle.getFillForegroundColorColor();
if (bgColor != null) {
short[]rgbColor = bgColor.getTriplet();
myCell.setBgColor("rgb(" + rgbColor[0]+ ","
+ rgbColor[1]+ "," + rgbColor[2]+ ")");
}
HSSFFont font = cell.getCellStyle().getFont(workbook);
-
JSP
ページで
CSS
を使用して表示しやすいように、色は
rgb(rVal、gVal、bVal)
形式で読み取られます。
フォントサイズ、太さ、色も取得しましょう。
myCell.setTextSize(font.getFontHeightInPoints() + "");
if (font.getBold()) {
myCell.setTextWeight("bold");
}
HSSFColor textColor = font.getHSSFColor(workbook);
if (textColor != null) {
short[]rgbColor = textColor.getTriplet();
myCell.setTextColor("rgb(" + rgbColor[0]+ ","
+ rgbColor[1]+ "," + rgbColor[2]+ ")");
}
3.2. .xlsxファイルの解析
-
より新しい
.xlsx
形式のファイルについては、リンクの/java-microsoft-excelにも記載されているように、ワークブックの内容に
XSSFWorkbook
クラス** と同様のファイルを使用できます。
.xlsx
形式のセルの書式設定について詳しく見てみましょう。まず、** セルに関連付けられた
XSSFCellStyle
オブジェクトを取得し、それを使用して背景色とフォントを決定します。
XSSFCellStyle cellStyle = cell.getCellStyle();
MyCell myCell = new MyCell();
XSSFColor bgColor = cellStyle.getFillForegroundColorColor();
if (bgColor != null) {
byte[]rgbColor = bgColor.getRGB();
myCell.setBgColor("rgb("
+ (rgbColor[0]< 0 ? (rgbColor[0]+ 0xff) : rgbColor[0]) + ","
+ (rgbColor[1]< 0 ? (rgbColor[1]+ 0xff) : rgbColor[1]) + ","
+ (rgbColor[2]< 0 ? (rgbColor[2]+ 0xff) : rgbColor[2]) + ")");
}
XSSFFont font = cellStyle.getFont();
この場合、色の
RGB
値は
signed byte
値になるので、
0xff
を負の値に加算して
unsigned
値を取得します。
フォントのプロパティも確認しましょう。
myCell.setTextSize(font.getFontHeightInPoints() + "");
if (font.getBold()) {
myCell.setTextWeight("bold");
}
XSSFColor textColor = font.getXSSFColor();
if (textColor != null) {
byte[]rgbColor = textColor.getRGB();
myCell.setTextColor("rgb("
+ (rgbColor[0]< 0 ? (rgbColor[0]+ 0xff) : rgbColor[0]) + ","
+ (rgbColor[1]< 0 ? (rgbColor[1]+ 0xff) : rgbColor[1]) + ","
+ (rgbColor[2]< 0 ? (rgbColor[2]+ 0xff) : rgbColor[2]) + ")");
}
3.3. 空の行を処理する
-
上記の方法では、Excelファイルの空の行は考慮されません** 空の行も表示するファイルの忠実な表現が必要な場合は、結果の
HashMap
で
MyCell
オブジェクトの
ArrayList
を使用してこれらをシミュレートする必要があります。コンテンツとして空の
Strings
を含みます。
最初、Excelファイルを読み込んだ後、ファイル内の空の行はサイズが0の
ArrayList
オブジェクトになります。
空の
String
オブジェクトをいくつ追加するかを決定するために、最初に
maxNrCols
変数を使用して、Excelファイル内の最長の行を決定します。それから、その数の空の
String
オブジェクトを、サイズが0の
HashMap
内のすべてのリストに追加します。
int maxNrCols = data.values().stream()
.mapToInt(List::size)
.max()
.orElse(0);
data.values().stream()
.filter(ls -> ls.size() < maxNrCols)
.forEach(ls -> {
IntStream.range(ls.size(), maxNrCols)
.forEach(i -> ls.add(new MyCell("")));
});
4 Excelファイルを表示する
Spring MVC
を使用して読み込んだExcelファイルを表示するには、コントローラーマッピングと
JSP
ページを定義する必要があります。
4.1. Spring MVCコントローラー
アップロードされたファイルの内容を読み取るために上記のコードを呼び出す
@ RequestMapping
メソッドを作成し、返された
Map
を
Model
属性として追加します。
@Resource(name = "excelPOIHelper")
private ExcelPOIHelper excelPOIHelper;
@RequestMapping(method = RequestMethod.GET, value = "/readPOI")
public String readPOI(Model model) throws IOException {
if (fileLocation != null) {
if (fileLocation.endsWith(".xlsx") || fileLocation.endsWith(".xls")) {
Map<Integer, List<MyCell>> data
= excelPOIHelper.readExcel(fileLocation);
model.addAttribute("data", data);
} else {
model.addAttribute("message", "Not a valid excel file!");
}
} else {
model.addAttribute("message", "File missing! Please upload an excel file.");
}
return "excel";
}
4.2. JSP
ファイルの内容を視覚的に表示するために、
HTML
table
を作成し、各テーブルセルの
style
属性に、Excelファイルから各セルに対応するフォーマットプロパティを追加します。
<c:if test="${not empty data}">
<table style="border: 1px solid black; border-collapse: collapse;">
<c:forEach items="${data}" var="row">
<tr>
<c:forEach items="${row.value}" var="cell">
<td style="border:1px solid black;height:20px;width:100px;
background-color:${cell.bgColor};color:${cell.textColor};
font-weight:${cell.textWeight};font-size:${cell.textSize}pt;">
${cell.content}
</td>
</c:forEach>
</tr>
</c:forEach>
</table>
</c:if>
5結論
この記事では、
Spring MVC
フレームワークを使用してExcelファイルをアップロードし、それらをWebページに表示するためのプロジェクト例を示しました。
完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-mvc-java[GitHubプロジェクト]にあります。