Загрузка и отображение файлов Excel с помощью Spring MVC

Загрузка и отображение файлов Excel с помощью Spring MVC

1. Вступление

В этой статье мы продемонстрируем, какupload Excel files and display their content in a web page использовать фреймворкSpring MVC.

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";
}

Затем давайте создадим файлJSP с формой, содержащейinput изtype file, для которого будет установлен атрибутaccept, разрешающий только файлы Excel:


3. Чтение файлов Excel

Чтобы проанализировать загруженный файл Excel, мы будем использовать библиотекуApache POI, которая может работать как с файлами.xls, так и.xlsx.

Давайте создадим вспомогательный класс под названиемMyCell, который будет содержать свойства ячейки Excel, связанные с содержимым и форматированием:

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 вMap, который содержит списки объектовMyCell.

3.1. Разбор файла .xls

A .xls file is represented in the Apache POI library by an HSSFWorkbookclass, который состоит из объектовHSSFSheet. Чтобы открыть и прочитать содержимое файла.xls, вы можете просмотреть нашу статью оWorking with Microsoft Excel in Java.

For parsing the formatting of a cell, we will obtain the HSSFCellStyleobject,, который может помочь нам определить такие свойства, как цвет фона и шрифт. Все свойства чтения будут установлены в атрибутах объекта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);

Цвета читаются в форматеrgb(rVal, gVal, bVal), чтобы упростить их отображение с помощьюCSS на страницеJSP.

Получим также размер, толщину и цвет шрифта:

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

For files in the newer .xlsx format, we can use the XSSFWorkbook class и аналогичные для содержимого книги, также задокументированные в статьеWorking with Microsoft Excel in Java.

Давайте подробнее рассмотрим чтение форматирования ячейки в формате.xlsx. Во-первых,we will retrieve the XSSFCellStyle object связан с ячейкой и использует его для определения цвета фона и шрифта:

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, поэтому мы получим значенияunsigned, добавив0xff к отрицательным значениям.

Давайте также определим свойства шрифта:

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. Обработка пустых строк

The methods described above do not account for empty rows in an Excel file. Если мы хотим точного воспроизведения файла, который также отображает пустые строки, нам нужно будет смоделировать их в нашем результирующемHashMap сArrayList объектовMyCell содержащий пустойStrings в качестве содержимого.

Первоначально после чтения файла Excel пустые строки в файле будут объектамиArrayList размером 0.

Чтобы определить, сколько пустых объектовString мы должны добавить, мы сначала определим самую длинную строку в файле Excel, используя переменнуюmaxNrCols. Затем мы добавим это количество пустых объектовString во все списки в нашемHashMap, размер которых равен 0:

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

Для отображения файлов Excel, прочитанных с использованиемSpring MVC, нам нужно будет определить отображение контроллера и страницуJSP.

4.1. Spring MVC Controller

Давайте создадим метод@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> 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

Для визуального отображения содержимого файла мы создадимHTMLtable и в атрибутеstyle каждой ячейки таблицы добавим свойства форматирования, соответствующие каждой ячейке из файла Excel. :


    
            
                    
${cell.content}

5. Заключение

В этой статье мы показали пример проекта для загрузки файлов Excel и отображения их на веб-странице с использованием фреймворкаSpring MVC.

Полный исходный код можно найти вGitHub project.