1. Введение
В этой статье мы покажем, как загружать файлы Excel и отображать их содержимое на веб-странице с помощью среды 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
с формой, которая содержит ввод
типа файла
, для которого будет установлен атрибут accept
, разрешающий только файлы Excel:
<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
Чтобы проанализировать загруженный файл 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 в карту
, содержащую списки объектов MyCell
.
3.1. Анализ файла .xls
Файл .xls
представлен в библиотеке POI Apache
`` классом HSSFWorkbook
, состоящим из объектов HSSFSheet
. Чтобы открыть и прочитать содержимое файла .xls
, вы можете просмотреть нашу статью Работа с Microsoft Excel в Java .
Для анализа форматирования ячейки мы получим объект 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);
Цвета считываются в формате 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
Для файлов в более новом формате .xlsx
мы можем использовать класс XSSFWorkbook
и аналогичные классы для содержимого книги, также описанные в статье « Работа с Microsoft Excel в Java ».
Давайте подробнее рассмотрим чтение форматирования ячейки в формате .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
цвета будут знаковыми байтовыми
значениями, поэтому мы получим значения без знака
, добавив 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. Обработка пустых строк
Описанные выше методы не учитывают пустые строки в файле Excel. Если нам нужно точное представление файла, в котором также отображаются пустые строки, нам нужно будет смоделировать их в нашем результирующем HashMap
с помощью ArrayList
объектов MyCell
, содержащих пустые строки
в качестве содержимого.
Первоначально, после чтения файла 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
Давайте создадим метод @RequestMapping
, который вызовет приведенный выше код для чтения содержимого загруженного файла, а затем добавит возвращенную карту
в качестве атрибута модели :
@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 -
таблицу
и в атрибуте стиля
каждой ячейки таблицы добавим свойства форматирования, соответствующие каждой ячейке из файла 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. Вывод
В этой статье мы показали пример проекта для загрузки файлов Excel и их отображения на веб-странице с использованием среды Spring MVC
.
Полный исходный код можно найти в проекте GitHub .