Carregar e exibir arquivos do Excel com o Spring MVC
1. Introdução
Neste artigo, demonstraremos comoupload Excel files and display their content in a web page usando a estruturaSpring MVC.
2. Carregando arquivos do Excel
Para poder fazer upload de arquivos, primeiro criaremos um mapeamento de controlador que recebe umMultipartFilee salva no local atual:
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";
}
A seguir, vamos criar um arquivoJSP com um formulário que contém uminput detype file que terá o atributoaccept definido para permitir apenas arquivos Excel:
3. Lendo arquivos do Excel
Para analisar o arquivo excel carregado, usaremos a bibliotecaApache POI, que pode trabalhar com arquivos.xlse.xlsx.
Vamos criar uma classe auxiliar chamadaMyCell que conterá propriedades de uma célula do Excel relacionadas ao conteúdo e formatação:
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
}
Leremos o conteúdo do arquivo Excel em umMap que contém listas de objetosMyCell.
3.1. Analisando um arquivo .xls
A .xls file is represented in the Apache POI library by an HSSFWorkbookclass, que é composto de objetosHSSFSheet. Para abrir e ler o conteúdo de um arquivo.xls, você pode ver nosso artigo emWorking with Microsoft Excel in Java.
For parsing the formatting of a cell, we will obtain the HSSFCellStyleobject, que pode nos ajudar a determinar propriedades como a cor de fundo e a fonte. Todas as propriedades de leitura serão definidas nos atributos do objetoMyCell:
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);
As cores são lidas no formatorgb(rVal, gVal, bVal) para tornar mais fácil exibi-las usandoCSS em uma páginaJSP.
Vamos também obter o tamanho, peso e cor da fonte:
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. Analisando um arquivo .xlsx
For files in the newer .xlsx format, we can use the XSSFWorkbook class e semelhantes para o conteúdo de uma pasta de trabalho, também documentados no artigoWorking with Microsoft Excel in Java.
Vamos dar uma olhada mais de perto na leitura da formatação de uma célula no formato.xlsx. Primeiro,we will retrieve the XSSFCellStyle object associado a uma célula e use-o para determinar a cor de fundo e fonte:
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();
Neste caso, os valores deRGB da cor serão os valores designed byte, portanto obteremos os valores deunsigned adicionando0xff aos valores negativos.
Vamos também determinar as propriedades da fonte:
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. Tratamento de linhas vazias
The methods described above do not account for empty rows in an Excel file. Se quisermos uma versão fiel do arquivo que exibe as linhas vazias também, precisaremos simular isso em nossoHashMap resultante com umArrayList de objetosMyCell contendoStrings vazio como conteúdo.
Inicialmente, após a leitura do arquivo Excel, as linhas vazias do arquivo serãoArrayList objetos com tamanho 0.
Para determinar quantos objetosString vazios devemos adicionar, determinaremos primeiro a linha mais longa no arquivo Excel, usando a variávelmaxNrCols. Em seguida, adicionaremos esse número de objetosString vazios a todas as listas em nossoHashMap que têm um tamanho de 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. Exibindo arquivos do Excel
Para exibir os arquivos Excel lidos usandoSpring MVC, precisaremos definir um mapeamento do controlador e a páginaJSP.
4.1. Spring MVC Controller
Vamos criar um método@RequestMapping que chamará o código acima para ler o conteúdo do arquivo carregado e, em seguida, adicionar oMap retornado como um atributoModel:
@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
Para exibir visualmente o conteúdo do arquivo, criaremos umHTMLtablee, no atributostyle de cada célula da tabela, adicionaremos as propriedades de formatação correspondentes a cada célula do arquivo Excel :
${cell.content}
5. Conclusão
Neste artigo, mostramos um projeto de exemplo para enviar arquivos do Excel e exibi-los em uma página da web usando a estruturaSpring MVC.
O código-fonte completo pode ser encontrado emGitHub project.