Browse Source

xlsx-проверить работоспособность

master
esoe 2 months ago
parent
commit
3582766baa
  1. 23
      storage/src/main/java/gsp/technologies/storage/controllers/api/ApiController.java
  2. 7
      storage/src/main/java/gsp/technologies/storage/models/xlsx/PageInfo.java
  3. 108
      storage/src/main/java/gsp/technologies/storage/models/xlsx/Xlsx.java
  4. 217
      storage/src/main/java/gsp/technologies/storage/models/xlsx/XlsxDocument.java
  5. 104
      storage/src/main/java/gsp/technologies/storage/models/xlsx/XlsxMultipartDocument.java
  6. 33
      storage/src/main/java/gsp/technologies/storage/models/xlsx/XlsxPage.java
  7. 2
      storage/src/main/java/gsp/technologies/storage/services/FileService.java
  8. 3
      storage/src/main/java/gsp/technologies/storage/services/FileServiceImpl.java

23
storage/src/main/java/gsp/technologies/storage/controllers/api/ApiController.java

@ -13,6 +13,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@ -23,6 +24,8 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import gsp.technologies.storage.models.FileMetadata; import gsp.technologies.storage.models.FileMetadata;
import gsp.technologies.storage.models.xlsx.Xlsx;
import gsp.technologies.storage.models.xlsx.XlsxPage;
import gsp.technologies.storage.services.FileService; import gsp.technologies.storage.services.FileService;
@Controller @Controller
@ -165,6 +168,26 @@ public class ApiController {
fs.deleteDirectory(name); fs.deleteDirectory(name);
} }
@GetMapping("/files/xlsx")
public String getXlsxPage(Model model,
@RequestParam(name = "filename", required = true) String filename,
@RequestParam(name = "pageNumber", defaultValue = "0") String pageNumber,
@RequestParam(name = "pageSize", defaultValue = "10") String pageSize) {
LOG.info("GET /files/xlsx");
LOG.info("filename: {}", filename);
LOG.info("pageNumber: {}", pageNumber);
LOG.info("pageSize: {}", pageSize);
Xlsx xlsx = new Xlsx(filename);
XlsxPage page = xlsx.page(Integer.parseInt(pageSize), Integer.parseInt(pageNumber));
/**
* проверить обработку xlsx на больших данных
*/
model.addAttribute("page", page);
return "view-xlsx";
}
} }

7
storage/src/main/java/gsp/technologies/storage/models/xlsx/PageInfo.java

@ -1,7 +0,0 @@
package gsp.technologies.storage.models.xlsx;
import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties.Pageable;
public class PageInfo{
}

108
storage/src/main/java/gsp/technologies/storage/models/xlsx/Xlsx.java

@ -0,0 +1,108 @@
package gsp.technologies.storage.models.xlsx;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import gsp.technologies.storage.models.FileMetadata;
public class Xlsx {
private static final Logger LOG = LoggerFactory.getLogger(Xlsx.class);
private FileMetadata metadata;
public Xlsx(FileMetadata metadata) {
this.metadata = metadata;
}
public Xlsx(String filename){
this.metadata = new FileMetadata(filename);
}
public XlsxPage page(int pageSize, int pageNumber) {
return XlsxPage.builder()
.pageSize(pageSize)
.pageNumber(pageNumber)
.metadata(metadata)
.content(this.content(pageSize, pageNumber))
.totalLines(this.totalLines())
.build();
}
Map<Integer, List<XlsxCell>> content(int pageSize, int pageNumber) {
Map<Integer, List<XlsxCell>> map = new HashMap<>();
try (InputStream is = new FileInputStream(metadata.getPath())) {
XSSFWorkbook wb = new XSSFWorkbook(is);
XSSFSheet sheet = wb.getSheetAt(0);
int numberOfRows = sheet.getPhysicalNumberOfRows();
int startRow = pageNumber * pageSize;
int endRow = Math.min(startRow + pageSize, numberOfRows);
for (int j = startRow; j < endRow; j++) {
Row row = sheet.getRow(j);
// do something with the row
List<XlsxCell> cells = new ArrayList<>();
if (row == null) continue; //пустая строка
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
cells.add(new XlsxCell(cell));
}
map.put(j, cells);
}
wb.close();
} catch (IOException e) {
LOG.info("IOException: " + e.getMessage());
}
return map;
}
/**
* Возвращает общее количество строк в документе
* @return
*/
public Integer totalLines() {
int count = 0;
try (InputStream is = new FileInputStream(metadata.getPath())) {
XSSFWorkbook wb = new XSSFWorkbook(is);
XSSFSheet sheet = wb.getSheetAt(0);
// count = sheet.getLastRowNum();
count = sheet.getPhysicalNumberOfRows();
// Iterator<Row> rowIterator = sheet.rowIterator();
// while (rowIterator.hasNext()) {
// Row row = rowIterator.next();
// Iterator<Cell> cellIterator = row.cellIterator();
// while (cellIterator.hasNext()) {
// Cell cell = cellIterator.next();
// // Use cell object to read data from the current cell
// }
// count++;
// }
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return count;
}
}

217
storage/src/main/java/gsp/technologies/storage/models/xlsx/XlsxDocument.java

@ -1,217 +0,0 @@
package gsp.technologies.storage.models.xlsx;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
// import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
// import lombok.AllArgsConstructor;
// import lombok.Data;
// import lombok.NoArgsConstructor;
// @Data
// @AllArgsConstructor
// @NoArgsConstructor
public class XlsxDocument implements Serializable{
private Map<Integer, List<XlsxCell>> data;
private Document document;
private List<XlsxCell> headers;//верхняя строка формы
public XlsxDocument(Document document){
this.document = document;
this.data = init(document);
this.headers = data.get(0);
}
private Map<Integer, List<XlsxCell>> init(Document document) {
// IOUtils.setByteArrayMaxOverride(Integer.MAX_VALUE);
FileInputStream file;
Workbook workbook;
try {
file = new FileInputStream(new File(document.getPath()));
workbook = new XSSFWorkbook(file);
Sheet sheet = workbook.getSheetAt(0);
data = new HashMap<>();
Integer i = 0;
//перебор строк
int rowStart = sheet.getFirstRowNum();
int rowEnd = sheet.getLastRowNum();
for (int rowNum = rowStart; rowNum < rowEnd; rowNum++){
Row r = sheet.getRow(rowNum);
if (r != null) {
//перебор ячеек в строке
List<XlsxCell> xlsxCells = new ArrayList<>();
XlsxCell xlsxCell = null;
int lastColumn = r.getLastCellNum();
for (int cn = 0; cn < lastColumn; cn++){
Cell cell = r.getCell(cn);
if (cell == null) {
//обработка нулевой ячейки
xlsxCell = new XlsxCell("");
xlsxCell.setType("NULL");
} else {
//обработка ячейки
switch (cell.getCellType()) {
case STRING: {
xlsxCell = new XlsxCell(cell.getStringCellValue() + "");
xlsxCell.setType("STRING");
} break;
case NUMERIC: {
if (DateUtil.isCellDateFormatted(cell)) {
xlsxCell = new XlsxCell(cell.getDateCellValue().getTime() + "" );
xlsxCell.setType("DATE");
} else {
xlsxCell = new XlsxCell(cell.getNumericCellValue() + "");
xlsxCell.setType("NUMERIC");
}
} break;
case BOOLEAN: {
xlsxCell = new XlsxCell(cell.getBooleanCellValue() + "");
xlsxCell.setType("BOOLEAN");
} break;
case FORMULA: {
xlsxCell = new XlsxCell(cell.getCellFormula() + "");
xlsxCell = new XlsxCell("FORMULA");
xlsxCell.setType("FORMULA");
} break;
case BLANK: {
xlsxCell = new XlsxCell("");
xlsxCell.setType("BLANK");
} break;
case ERROR: {
xlsxCell = new XlsxCell("");
xlsxCell.setType("ERROR");
} break;
case _NONE: {
xlsxCell = new XlsxCell("");
xlsxCell.setType("_NONE");
} break;
}
}
xlsxCells.add(xlsxCell);
}
data.put(rowNum, xlsxCells);
}
}
}catch (IOException e) {
System.out.println("Не читается файл: " + e.getMessage());
}
return data;
}
/**
* @return the data
*/
public Map<Integer, List<XlsxCell>> getData() {
return data;
}
/**
* @param data the data to set
*/
public void setData(Map<Integer, List<XlsxCell>> data) {
this.data = data;
}
/**
* @return the document
*/
public Document getDocument() {
return document;
}
/**
* @param document the document to set
*/
public void setDocument(Document document) {
this.document = document;
}
/**
* @return the headers
*/
public List<XlsxCell> getHeaders() {
return headers;
}
/**
* @param headers the headers to set
*/
public void setHeaders(List<XlsxCell> headers) {
this.headers = headers;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((data == null) ? 0 : data.hashCode());
result = prime * result + ((document == null) ? 0 : document.hashCode());
result = prime * result + ((headers == null) ? 0 : headers.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
XlsxDocument other = (XlsxDocument) obj;
if (data == null) {
if (other.data != null)
return false;
} else if (!data.equals(other.data))
return false;
if (document == null) {
if (other.document != null)
return false;
} else if (!document.equals(other.document))
return false;
if (headers == null) {
if (other.headers != null)
return false;
} else if (!headers.equals(other.headers))
return false;
return true;
}
@Override
public String toString() {
return "XlsxDocument [data=" + data + ", document=" + document + ", headers=" + headers + "]";
}
/**
* @param data
* @param document
* @param headers
*/
public XlsxDocument(Map<Integer, List<XlsxCell>> data, Document document, List<XlsxCell> headers) {
this.data = data;
this.document = document;
this.headers = headers;
}
/**
*
*/
public XlsxDocument() {
}
}

104
storage/src/main/java/gsp/technologies/storage/models/xlsx/XlsxMultipartDocument.java

@ -1,104 +0,0 @@
package gsp.technologies.storage.models.xlsx;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Данные извлекаемые из файла порциями заданного размера
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class XlsxMultipartDocument {
private Document document;
private FileInputStream fis;
private Workbook workbook;
private Sheet sheet;
public XlsxMultipartDocument(Document document){
this.document = document;
try {
this.fis = new FileInputStream(new File(document.getPath()));
this.workbook = new XSSFWorkbook(fis);
this.sheet = workbook.getSheetAt(0);
} catch (IOException e) {
System.out.println("Не читается файл: " + e.getMessage());
}
}
/**
* Получение физического количества строк в документе,
* что бы это не значило
* @return
*/
public int getLineCount() {
return sheet.getPhysicalNumberOfRows();
}
public List<XlsxCell> line(int n) {
Row row = sheet.getRow(n);
List<XlsxCell> cells = new ArrayList<>();
if (row == null) return cells; //пустая строка
int i = 0;
int max = row.getLastCellNum();
for (; i < max; i++) {
Cell cell = row.getCell(i);
cells.add(new XlsxCell(cell));
}
return cells;
}
public void close() {
try {
workbook.close();
fis.close();
} catch (IOException e) {
System.out.println("Не удалось закрыть потоки: " + e.getMessage());
}
}
public Map<Integer, List<XlsxCell>> lines(int from, int count) {
Map<Integer, List<XlsxCell>> lines = new HashMap<>();
for (int i = from; i < from + count; i++) {
lines.put(i, line(i));
}
return lines;
}
public List<XlsxCell> column(int num) {
List<XlsxCell> cells = new ArrayList<>();
for (int i = 0; i < getLineCount(); i++) {
cells.add(line(i).get(num));
}
return cells;
}
public List<XlsxCell> columnUnique(int num) {
List<XlsxCell> cells = new ArrayList<>();
for (int i = 0; i < getLineCount(); i++) {
if (!cells.contains(line(i).get(num)))
cells.add(line(i).get(num));
}
return cells;
}
}

33
storage/src/main/java/gsp/technologies/storage/models/xlsx/XlsxPage.java

@ -1,19 +1,50 @@
package gsp.technologies.storage.models.xlsx; package gsp.technologies.storage.models.xlsx;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import gsp.technologies.storage.models.FileMetadata; import gsp.technologies.storage.models.FileMetadata;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/** /**
* Класс для хранения содержимого страницы, * Класс для хранения содержимого страницы,
* сформированной из данных xlsx-файла * сформированной из данных xlsx-файла
*/ */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class XlsxPage { public class XlsxPage {
private Map<Integer, List<XlsxCell>> content; private Map<Integer, List<XlsxCell>> content;
private FileMetadata metadata; private FileMetadata metadata;
private PageInfo info
//информация о странице
private int pageSize;//размер страницы, количество строк на странице
private int pageNumber;//номер текущей страницы
private int offset;//смещение начала извлечения данных из файла
private int headerLine;//номер строки в файле, содержащей заголовки
//сведения о положении страницы среди общей выборки страниц
private boolean last;//последняя страница
private boolean first;//первая страница
private boolean hasNext;//есть ли следующая страница
private boolean hasPrevious;//есть ли предыдущая страница
//информация о документе
private long totalLines;//общее количество строк
private int totalColumns;//общее количество столбцов
private int totalPages;//общее количество страниц
public XlsxPage(FileMetadata metadata, int pageSize, int pageNumber, int offset, int headerLine) {
this.metadata = metadata;
this.pageSize = pageSize;
this.pageNumber = pageNumber;
this.headerLine = headerLine;
this.offset = offset;
// init();
}
} }

2
storage/src/main/java/gsp/technologies/storage/services/FileService.java

@ -20,7 +20,7 @@ public interface FileService {
String createFile(String path, String name, byte[] content); String createFile(String path, String name, byte[] content);
void createDirectory(String path, String name); void createDirectory(String path, String name);
void deleteDirectory(String name); void deleteDirectory(String name);
public Path root(); Path root();
void init(); void init();
Resource loadAsResource(String filename); Resource loadAsResource(String filename);
List<FileMetadata> store(MultipartFile[] files); List<FileMetadata> store(MultipartFile[] files);

3
storage/src/main/java/gsp/technologies/storage/services/FileServiceImpl.java

@ -20,14 +20,15 @@ import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import gsp.technologies.storage.config.StorageConfig; import gsp.technologies.storage.config.StorageConfig;
import gsp.technologies.storage.controllers.api.ApiController;
import gsp.technologies.storage.models.FileMetadata; import gsp.technologies.storage.models.FileMetadata;
import gsp.technologies.storage.models.xlsx.XlsxPage;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
@Service @Service
public class FileServiceImpl implements FileService { public class FileServiceImpl implements FileService {
private static final Logger LOG = LoggerFactory.getLogger(FileServiceImpl.class); private static final Logger LOG = LoggerFactory.getLogger(FileServiceImpl.class);
private final Path storageLocation; private final Path storageLocation;
public FileServiceImpl(StorageConfig config) { public FileServiceImpl(StorageConfig config) {
this.storageLocation = Paths.get(config.getLocation()) this.storageLocation = Paths.get(config.getLocation())
.toAbsolutePath().normalize(); .toAbsolutePath().normalize();

Loading…
Cancel
Save