Запишите содержимое Flowfile в файл Excel (или xls) с помощью Groovy

Я использую Apache Nifi для извлечения данных SQL-запроса в файл XLS.

Я использую ExecuteQuery для извлечения данных в Avro, а затем в CSV с помощью CSV RecordWriter.

Теперь я должен иметь свои данные в файле XLS, для этого я использую этот скрипт Groovy, но он не работает:

// import org.apache.commons.io.IOUtils
import java.nio.charset.*
// import java.text.SimpleDateFormat
import java.io.*

import org.apache.poi.ss.usermodel.*
import org.apache.poi.hssf.usermodel.*
import org.apache.poi.xssf.usermodel.*
import org.apache.poi.ss.util.*
import org.apache.poi.ss.usermodel.*
import org.apache.poi.hssf.extractor.*

def flowFile = session.get()

if (!flowFile) return

flowFile = session.write(flowFile, {inputStream, outputStream ->
    try {

     inputStream.writeTo(outputStream)
 
// i tried also outputStream.write(inputStream)
 
//i  tried also to retrieve the excel file with:
 //Workbook wb = WorkbookFactory.create(inputStream)
//and write with : outputStream.write(wb)
 
    }
    catch(e) {
     log.error("Error during processing", e)
     session.transfer(flowFile, REL_FAILURE)
    }
} as StreamCallback)

session.transfer(flowFile, REL_SUCCESS)

У меня есть эта ошибка:

Редактировать: Я изменил свой сценарий и получил другую ошибку:

@Grapes(@Grab(group='org.apache.poi', module='poi-ooxml', version='3.9'))
import com.opencsv.CSVReader
@Grapes(@Grab(group='com.opencsv', module='opencsv', version='4.2'))
import org.apache.poi.ss.usermodel.*
import org.apache.poi.xssf.streaming.*
import org.apache.poi.hssf.usermodel.*
import org.apache.poi.xssf.usermodel.*
import org.apache.poi.ss.util.*
import org.apache.poi.ss.usermodel.*
import org.apache.poi.hssf.extractor.*
import java.nio.charset.*
import java.io.*
import org.apache.commons.io.IOUtils

def flowFile = session.get()
def date = new Date()

if (!flowFile) return


flowFile = session.write(flowFile, {inputStream, outputStream ->
        SXSSFSheet sheet1 = null;
        CSVReader reader = null;
        Workbook wb = null;
        String generatedXlsFilePath = "/home/";
        FileOutputStream fileOutputStream = null;
  
  def filename = flowFile.getAttribute('filename')
  def path = flowFile.getAttribute('path')
  
            def nextLine = ''
            reader = new CSVReader(new FileReader(path+filename), ',');
 
 //Workbook wb = WorkbookFactory.create(inputStream,);
 //Sheet sheet1 = wb.createSheet("Feuille");
 
            wb = new SXSSFWorkbook(inputStream);
            sheet1 = (SXSSFSheet) wb.createSheet('Sheet');
 
            def rowNum = 0;
            while((nextLine = reader.readNext()) != null) {
                Row currentRow = sheet1.createRow(rowNum++);
                for(int i=0; i < nextLine.length; i++) {
                    if (NumberUtils.isDigits(nextLine[i])) {
                        currentRow.createCell(i).setCellValue(Integer.parseInt(nextLine[i]));
                    } else if (NumberUtils.isNumber(nextLine[i])) {
                        currentRow.createCell(i).setCellValue(Double.parseDouble(nextLine[i]));
                    } else {
                        currentRow.createCell(i).setCellValue(nextLine[i]);
                    }
                }
            }
  
 
            //fileOutputStream = new FileOutputStream(generatedXlsFilePath.trim());
            //wb.write(fileOutputStream);
            generatedXlsFilePath = generatedXlsFilePath + 'SAISIE_MAGASING.XLS'
            outputStream = new FileOutputStream(generatedXlsFilePath.trim());
 
            wb.write(outputStream);
            
                wb.close();
                //fileOutputStream.close();
                outputStream.close();
                reader.close();
                //outputStream.close();
                inputStream.close();
                
  
} as StreamCallback)



flowFile = session.putAttribute(flowFile, 'filename', filename) 

Новая ошибка:

1. Вы не должны делать передачу внутри потока записи 2. Я рекомендую вам использовать процессор executegroovyscript

daggett 10.12.2022 09:12

Я использую скрипт выполнения groovy, как показано на экране. Что не так с моим сценарием §?

O. Sam 21.12.2022 22:30

. Вы не должны делать передачу внутри метода записи потокового файла. Вы можете просто отказаться от try-catch, потому что executegroovyscript правильно обрабатывает ошибки.

daggett 22.12.2022 07:09

@daggett Я добавил новый скрипт в свой пост, у меня есть другая ошибка: Нет такого каталога .... как я могу передать содержимое потокового файла (содержимое csv) в класс Filereader? Спасибо

O. Sam 30.12.2022 02:01

содержимое потокового файла проходит через inputStream, и вы можете изменить его с помощью outputStream. примерно этот код должен создать новый ридер opencsv: new CSVReader( inputStream.newReader('UTF-8') )

daggett 30.12.2022 15:24

@daggett Спасибо за помощь. Делюсь отработанным скриптом в качестве ответа.

O. Sam 03.01.2023 01:07
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
1
6
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Благодаря @dagget

Это рабочий скрипт:

@Grapes(@Grab(group='org.apache.poi', module='poi-ooxml', version='3.9'))
import com.opencsv.CSVReader
@Grapes(@Grab(group='com.opencsv', module='opencsv', version='4.2'))
//@Grapes(@Grab(group='org.apache.commons', module='lang', version='3.12.0'))

@Grapes(@Grab(group='commons-lang', module='commons-lang', version='2.4'))
import org.apache.commons.lang.*


import org.apache.poi.ss.usermodel.*
import org.apache.poi.xssf.streaming.*
import org.apache.poi.hssf.usermodel.*
import org.apache.poi.xssf.usermodel.*
import org.apache.poi.ss.util.*
import org.apache.poi.ss.usermodel.*
import org.apache.poi.hssf.extractor.*
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import java.nio.charset.*
import java.io.*
import org.apache.commons.io.IOUtils


def flowFile = session.get()
def date = new Date()

if (!flowFile) return


flowFile = session.write(flowFile, {inputStream, outputStream ->
        SXSSFSheet sheet1 = null;
        CSVReader reader = null;
        Workbook wb = null;
        
  
 
            def nextLine = ''
            reader = new CSVReader( inputStream.newReader('UTF-8') );
            wb = new SXSSFWorkbook();
            sheet1 = (SXSSFSheet) wb.createSheet('Sheet');
 
            def rowNum = 0
            while((nextLine = reader.readNext()) != null) {
                Row currentRow = sheet1.createRow(rowNum++);
                for(int i=0; i < nextLine.length; i++) {
                    if (NumberUtils.isDigits(nextLine[i])) {
                        currentRow.createCell(i).setCellValue(Integer.parseInt(nextLine[i]));
                    } else if (NumberUtils.isNumber(nextLine[i])) {
                        currentRow.createCell(i).setCellValue(Double.parseDouble(nextLine[i]));
                    } else {
                        currentRow.createCell(i).setCellValue(nextLine[i]);
                    }
                }
            }
  
 

            wb.write(outputStream);
            reader.close();

} as StreamCallback)


  def filename = 'toto.xlsx'
flowFile = session.putAttribute(flowFile, 'filename', filename) 

session.transfer(flowFile, REL_SUCCESS)

Другие вопросы по теме