esoe
2 months ago
8 changed files with 602 additions and 1 deletions
@ -0,0 +1,7 @@ |
|||||||
|
package gsp.technologies.storage.models.xlsx; |
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties.Pageable; |
||||||
|
|
||||||
|
public class PageInfo{ |
||||||
|
|
||||||
|
} |
@ -0,0 +1,163 @@ |
|||||||
|
package gsp.technologies.storage.models.xlsx; |
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.Cell; |
||||||
|
import org.apache.poi.ss.usermodel.DateUtil; |
||||||
|
|
||||||
|
import gsp.technologies.storage.util.Stringer; |
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Класс для хранения содержимого ячейки |
||||||
|
* TODO: убрать не нужные поля |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class XlsxCell { |
||||||
|
private String content; //содержимое ячейки
|
||||||
|
private String type;// STRING, NUMERIC, BOOLEAN, FORMULA
|
||||||
|
|
||||||
|
public XlsxCell(String content){ |
||||||
|
setContent(content); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the content |
||||||
|
*/ |
||||||
|
public String getContent() { |
||||||
|
return content; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param content the content to set |
||||||
|
*/ |
||||||
|
public void setContent(String content) { |
||||||
|
//убираем лишние пробельные символы
|
||||||
|
//заменяем пустые строки на ""
|
||||||
|
this.content = Stringer.clear(content); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the type |
||||||
|
*/ |
||||||
|
public String getType() { |
||||||
|
return type; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param type the type to set |
||||||
|
*/ |
||||||
|
public void setType(String type) { |
||||||
|
this.type = type; |
||||||
|
} |
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public int hashCode() {
|
||||||
|
// final int prime = 31;
|
||||||
|
// int result = 1;
|
||||||
|
// result = prime * result + ((content == null) ? 0 : content.hashCode());
|
||||||
|
// result = prime * result + ((type == null) ? 0 : type.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;
|
||||||
|
// XlsxCell other = (XlsxCell) obj;
|
||||||
|
// if (content == null) {
|
||||||
|
// if (other.content != null)
|
||||||
|
// return false;
|
||||||
|
// } else if (!content.equals(other.content))
|
||||||
|
// return false;
|
||||||
|
// if (type == null) {
|
||||||
|
// if (other.type != null)
|
||||||
|
// return false;
|
||||||
|
// } else if (!type.equals(other.type))
|
||||||
|
// return false;
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public String toString() {
|
||||||
|
// return "XlsxCell [content=" + content + ", type=" + type + "]";
|
||||||
|
// }
|
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
*/ |
||||||
|
public XlsxCell() { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param content |
||||||
|
* @param textColor |
||||||
|
* @param bgColor |
||||||
|
* @param textSize |
||||||
|
* @param textWeight |
||||||
|
* @param type |
||||||
|
*/ |
||||||
|
public XlsxCell(String content, String type) { |
||||||
|
this.setContent(content); |
||||||
|
this.setType(type); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* перенос данных из ячейки файла в объект java |
||||||
|
* TODO: прогнать контент ячейки через Stringer.Clear() |
||||||
|
* @param cell |
||||||
|
*/ |
||||||
|
public XlsxCell(Cell cell) { |
||||||
|
//обработка null
|
||||||
|
if (cell == null) { |
||||||
|
this.setContent(""); |
||||||
|
this.setType("NULL"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// обработка ячейки
|
||||||
|
switch (cell.getCellType()) { |
||||||
|
case STRING: |
||||||
|
this.setContent(cell.getStringCellValue()); |
||||||
|
this.setType("STRING"); |
||||||
|
break; |
||||||
|
case NUMERIC: |
||||||
|
if (DateUtil.isCellDateFormatted(cell)) { |
||||||
|
this.setContent(String.valueOf(cell.getDateCellValue().getTime() + "" )); |
||||||
|
this.setType("DATE"); |
||||||
|
} else { |
||||||
|
this.setContent(String.valueOf(cell.getNumericCellValue() + "")); |
||||||
|
this.setType("NUMERIC"); |
||||||
|
} |
||||||
|
break; |
||||||
|
case FORMULA: |
||||||
|
this.setContent(String.valueOf(cell.getCellFormula() + "")); |
||||||
|
this.setType("FORMULA"); |
||||||
|
break; |
||||||
|
case BOOLEAN: |
||||||
|
this.setContent(String.valueOf(cell.getBooleanCellValue())); |
||||||
|
this.setType("BOOLEAN"); |
||||||
|
break; |
||||||
|
case BLANK: |
||||||
|
this.setContent(""); |
||||||
|
this.setType("BLANK"); |
||||||
|
break; |
||||||
|
case ERROR: |
||||||
|
this.setContent(""); |
||||||
|
this.setType("ERROR"); |
||||||
|
break; |
||||||
|
case _NONE: |
||||||
|
this.setContent(""); |
||||||
|
this.setType("_NONE"); |
||||||
|
break; |
||||||
|
default: |
||||||
|
this.setContent(""); |
||||||
|
this.setType("_NONE"); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,217 @@ |
|||||||
|
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() { |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,104 @@ |
|||||||
|
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; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
package gsp.technologies.storage.models.xlsx; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import gsp.technologies.storage.models.FileMetadata; |
||||||
|
|
||||||
|
/** |
||||||
|
* Класс для хранения содержимого страницы, |
||||||
|
* сформированной из данных xlsx-файла |
||||||
|
*/ |
||||||
|
public class XlsxPage { |
||||||
|
private Map<Integer, List<XlsxCell>> content; |
||||||
|
private FileMetadata metadata; |
||||||
|
private PageInfo info |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,72 @@ |
|||||||
|
package gsp.technologies.storage.util; |
||||||
|
|
||||||
|
/** |
||||||
|
* Класс для работы со строками |
||||||
|
*/ |
||||||
|
public class Stringer { |
||||||
|
|
||||||
|
/** |
||||||
|
* Проверяет, является ли переданная строка null, пустой строкой или состоит только из пробелов. |
||||||
|
* |
||||||
|
* @param str Строка для проверки |
||||||
|
* @return True если строка является null, пустой строкой или состоит только из пробелов |
||||||
|
* False в противном случае |
||||||
|
*/ |
||||||
|
public static Boolean checkForEmpty(String str) { |
||||||
|
// Check if the string is null
|
||||||
|
if (str == null) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
// Check if the string is empty or consists only of whitespace characters
|
||||||
|
if (str.isEmpty() || str.trim().isEmpty()) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
// The string is not null, not empty and does not consist only of whitespace characters
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Удаляет регулярным выражением лишние пробельные символы из строки. |
||||||
|
* |
||||||
|
* Заменяет знаки переноса строки на пробелы с помощью использования регулярного выражения |
||||||
|
* \s+ - пробелы (и все ниже приведенные пробельные символы) |
||||||
|
* \t - табуляция |
||||||
|
* \v - вертикальная табуляция |
||||||
|
* \r - перенос в начало строки |
||||||
|
* \n - перенос строки |
||||||
|
* \f - форматированный перенос строки |
||||||
|
* |
||||||
|
* Осавляет по одному пробелу между словами, если слов больше одного |
||||||
|
* Возвращает пустую строку, если получена строка null |
||||||
|
* |
||||||
|
* @param string строка для обработки |
||||||
|
* @return строку без лишних пробелов или пустую строку |
||||||
|
*/ |
||||||
|
public static String clear(String string) { |
||||||
|
// Проверяем, не является ли строка null. Если строка null, возвращаем пустую строку.
|
||||||
|
if (string == null) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
|
||||||
|
// Удаляем лишние пробелы из строки.
|
||||||
|
return string.replaceAll("\\s+", " ").trim(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @param str |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static boolean isEmpty(String str) { |
||||||
|
// Check if the string is null
|
||||||
|
if (str == null) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
// Check if the string is empty or consists only of whitespace characters
|
||||||
|
if (str.isEmpty() || str.trim().isEmpty()) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
// The string is not null, not empty and does not consist only of whitespace characters
|
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue