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プロジェクト]にあります。