LINUX.ORG.RU

Помощь с Apache POI в java

 , ,


0

1

Подскажите, кто хорошо владеет библиотекой Apache POI на java. У меня есть ежедневная рутинная задача на работе, для которой я написал код и он в принципе работает, но значительную часть действий нужно всё таки совершать в ручную. Хочу улучшить. Ниже код, прошу сильно не ругать, я не профессиональный программист. Суть его следующая - есть пустой бланк образец, с формой на первой странице и два скачанных файла с межсетевого экрана. Один файл - логи по входам в систему, второй файл - почтовый трафик. Код создаёт новый файл, полностью копирует образец на первый лист, а на его второй и третий лист копирует содержимое файла логов входа и почты в те столбцы, которые я ему прописал.

public class Report {

	public static void main(String[] args) throws IOException {
		
		String filenameIndentity = getFileName("C:\\Users\\username\\Downloads", "^FileNameLog");
		String filenameMTA = getFileName("C:\\Users\\username\\Downloads", "^FileNameEmail");
		String filenameRepord = getFileName("S:\\папка\\46\\Отчёты 10.2022", "^отчёт за сутки образец");
		
		FileInputStream fileRepord = new FileInputStream(new File(filenameRepord));
		XSSFWorkbook repord = new XSSFWorkbook(fileRepord);
		Sheet sheetIndentity = repord.getSheet("в сети ООО \"Имя компании\"");
		Sheet sheeeetMTA = repord.getSheet("почта 24");
		
		FileInputStream fileIndentity = new FileInputStream(new File(filenameIndentity));
		XSSFWorkbook indentity = new XSSFWorkbook(fileIndentity);
		Sheet logIndentity = indentity.getSheet("Logs_Table");	
		
		FileInputStream fileMTA = new FileInputStream(filenameMTA);
		XSSFWorkbook mta = new XSSFWorkbook(fileMTA);
		Sheet logMTA = mta.getSheet("Logs_Table");	
		
		Set<Integer> columns = new HashSet<Integer>();
		Row row2 = null;
		Cell cell2 = null;
		for (Row row1 : logIndentity) {	
		    row2 = sheetIndentity.createRow(row1.getRowNum());	  
		     for (Cell cell1 : row1) {	

//в строке ниже зачастую необходимый индекс не равен 23,
//межсетевой экран часто делает файл где он нужен 24. Подскажите,
//как реализовать здесь проверку, чтобы проверялось содержимое
//ячейки и в случае, если в ней цифры, менять индекс с 23 на 24
//либо с 24 на 23. 	
   
			     if (cell1.getColumnIndex() == 23) {  
				     columns.add(cell1.getColumnIndex());
				     cell2 = row2.createCell(0);
				     copyCells(cell1, cell2);
			     }
		     }
		 }
		
		
		
		for (Row row1 : logMTA) {
			row2 = sheeeetMTA.createRow(row1.getRowNum());
			 for (Cell cell1 : row1) {
				 if (cell1.getColumnIndex() == 12) {
					 columns.add(cell1.getColumnIndex());
					 cell2 = row2.createCell(0);
					 copyCells(cell1, cell2);
				 } else if (cell1.getColumnIndex() == 38) {
					 columns.add(cell1.getColumnIndex());
					 cell2 = row2.createCell(1);
					 copyCells(cell1, cell2);					 
				 } else if (cell1.getColumnIndex() == 39) {
					 columns.add(cell1.getColumnIndex());
					 cell2 = row2.createCell(2);
					 copyCells(cell1, cell2);	
				 }
				 
			 }
		}


		  for (Integer column : columns) {
		   sheetIndentity.autoSizeColumn(column);
		  }	
		  
		  FileOutputStream out = new FileOutputStream("S:\\папка\\отчёт за сутки 21.10.2022.xlsx");
		  repord.write(out);
		  out.close();
		  repord.close(); 
		  fileRepord.close();
		  fileMTA.close();
		  fileIndentity.close();
		 
		  final Logger logger = Logger.getLogger(Report.class.getName());
		  logger.info("Собрал, всё ахеренно, отправляй");
		 
	}
	
	static Font copyFont(Font font1, Workbook wb2) {
		  boolean isBold = font1.getBold();
		  short color = font1.getColor();
		  short fontHeight = font1.getFontHeight();
		  String fontName = font1.getFontName();
		  boolean isItalic = font1.getItalic();
		  boolean isStrikeout = font1.getStrikeout();
		  short typeOffset = font1.getTypeOffset();
		  byte underline = font1.getUnderline();

		  Font font2 = wb2.findFont(isBold, color, fontHeight, fontName, isItalic, isStrikeout, typeOffset, underline);
		  if (font2 == null) {
		   font2 = wb2.createFont();
		   font2.setBold(isBold);
		   font2.setColor(color);
		   font2.setFontHeight(fontHeight);
		   font2.setFontName(fontName);
		   font2.setItalic(isItalic);
		   font2.setStrikeout(isStrikeout);
		   font2.setTypeOffset(typeOffset);
		   font2.setUnderline(underline);
		  }

		  return font2;
		 }
	
	 static void copyStyles(Cell cell1, Cell cell2) {
		  CellStyle style1 = cell1.getCellStyle();
		  Map<String, Object> properties = new HashMap<String, Object>();

		  //CellUtil.DATA_FORMAT
		  short dataFormat1 = style1.getDataFormat();
		  if (BuiltinFormats.getBuiltinFormat(dataFormat1) == null) {
		   String formatString1 = style1.getDataFormatString();
		   DataFormat format2 = cell2.getSheet().getWorkbook().createDataFormat();
		   dataFormat1 = format2.getFormat(formatString1);
		  }
		  properties.put(CellUtil.DATA_FORMAT, dataFormat1);

		  //CellUtil.FILL_PATTERN  
		  //CellUtil.FILL_FOREGROUND_COLOR 
		  FillPatternType fillPattern = style1.getFillPattern();
		  short fillForegroundColor = style1.getFillForegroundColor(); //gets only indexed colors, no custom HSSF or XSSF colors
		  properties.put(CellUtil.FILL_PATTERN, fillPattern);
		  properties.put(CellUtil.FILL_FOREGROUND_COLOR, fillForegroundColor);

		  //CellUtil.FONT
		  Font font1 = cell1.getSheet().getWorkbook().getFontAt(style1.getFontIndexAsInt());
		  Font font2 = copyFont(font1, cell2.getSheet().getWorkbook());
		  properties.put(CellUtil.FONT, font2.getIndexAsInt());

		  //BORDERS
		  BorderStyle borderStyle = null;
		  short borderColor = -1;
		  //CellUtil.BORDER_LEFT 
		  //CellUtil.LEFT_BORDER_COLOR
		  borderStyle = style1.getBorderLeft();
		  properties.put(CellUtil.BORDER_LEFT, borderStyle);
		  borderColor = style1.getLeftBorderColor();
		  properties.put(CellUtil.LEFT_BORDER_COLOR, borderColor);
		  //CellUtil.BORDER_RIGHT 
		  //CellUtil.RIGHT_BORDER_COLOR
		  borderStyle = style1.getBorderRight();
		  properties.put(CellUtil.BORDER_RIGHT, borderStyle);
		  borderColor = style1.getRightBorderColor();
		  properties.put(CellUtil.RIGHT_BORDER_COLOR, borderColor);
		  //CellUtil.BORDER_TOP 
		  //CellUtil.TOP_BORDER_COLOR
		  borderStyle = style1.getBorderTop();
		  properties.put(CellUtil.BORDER_TOP, borderStyle);
		  borderColor = style1.getTopBorderColor();
		  properties.put(CellUtil.TOP_BORDER_COLOR, borderColor);
		  //CellUtil.BORDER_BOTTOM 
		  //CellUtil.BOTTOM_BORDER_COLOR
		  borderStyle = style1.getBorderBottom();
		  properties.put(CellUtil.BORDER_BOTTOM, borderStyle);
		  borderColor = style1.getBottomBorderColor();
		  properties.put(CellUtil.BOTTOM_BORDER_COLOR, borderColor);

		  CellUtil.setCellStyleProperties(cell2, properties);
		 }
	 static void copyCells(Cell cell1, Cell cell2) {
		  switch (cell1.getCellType()) {
		   case STRING:
		   /*
		    //TODO: copy HSSFRichTextString to XSSFRichTextString 
		    RichTextString rtString1 = cell1.getRichStringCellValue();
		    cell2.setCellValue(rtString1); // this fails if cell2 is XSSF and rtString1 is HSSF
		   */
		    String string1 = cell1.getStringCellValue();
		    cell2.setCellValue(string1);
		   break;
		   case NUMERIC:
		    if (DateUtil.isCellDateFormatted(cell1)) {
		     Date date1 = cell1.getDateCellValue();
		     cell2.setCellValue(date1);
		    } else {
		     double cellValue1 = cell1.getNumericCellValue();
		     cell2.setCellValue(cellValue1);
		    }
		   break;
		   case FORMULA:
		    String formula1 = cell1.getCellFormula();
		    cell2.setCellFormula(formula1);
		   break;

		   //case : //TODO: further cell types

		  }

		  copyStyles(cell1, cell2);

		 }	
	 
	 public static String getFileName(String pFilePath, String pFilePattern) throws IOException {

		 Pattern pattern = Pattern.compile(pFilePattern);
		 String fileName = null;
		 File fileDir = new File(pFilePath);
		 File[] listFiles = fileDir.listFiles();

		 if (listFiles != null) {
		 for (int i = 0; i < listFiles.length; i++) {
		 // ignore directories
		 if (listFiles[i].isDirectory()) {
		 continue;
		 }
		 Matcher fileMatcher = pattern.matcher(listFiles[i].getName());
		 if (fileMatcher.find()) {
		 fileName = listFiles[i].getCanonicalPath();
		 }
		 } // end for()
		 }

		 return fileName;
		 }
	
}

В конечном файле в ручную на третьем листе с почтой удаляю первую строку листа, а на втором листе с логами входа в систему удаляю первую строку листа, сортирую список в единственном столбце (индекс 0), удаляю дубликаты и удаляю некоторые ненужные учётки (начинаются со слов администратор, пользователь, представитель), нужны только фио сотрудников. Подскажите как это реализовать кодом и как реализовать то что закомментировано в коде выше.

wb = new XSSWorkBook(…)

на третьем листе с почтой

sheet = wb.getSheet(2)

удаляю первую строку листа

sheet.removeRow(0)

а на втором листе с логами входа

wb.getSheet(1)

удаляю первую строку листа,

sheet.removeRow(0)

сортирую список в единственном столбце (индекс 0), удаляю дубликаты и удаляю некоторые ненужные учётки

А тут уже наверное проще будет пройтись итератором, загрузить все данные в коллекцию (ArrayList или даже HashMap), там всё сделать и записать обратно. Возможно, стерев всё содержимое предварительно. Если размер таблицы не огромный (но с огромными POI всё равно плохо справляется, так что сомневаюсь).

У sheet есть rowIterator, у а row есть cellIterator, у cell, соответственно, getCellValue и setCellValue.

Или можно по индексам, если вам так удобнее.

Всё ответы есть тут https://poi.apache.org/apidocs/5.0/

С вас $9,000 за консультацию.

BattleCoder ★★★★★
()
Последнее исправление: BattleCoder (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.