Я использую 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)
Новая ошибка:
Я использую скрипт выполнения groovy, как показано на экране. Что не так с моим сценарием §?
. Вы не должны делать передачу внутри метода записи потокового файла. Вы можете просто отказаться от try-catch, потому что executegroovyscript правильно обрабатывает ошибки.
@daggett Я добавил новый скрипт в свой пост, у меня есть другая ошибка: Нет такого каталога .... как я могу передать содержимое потокового файла (содержимое csv) в класс Filereader? Спасибо
содержимое потокового файла проходит через inputStream
, и вы можете изменить его с помощью outputStream
. примерно этот код должен создать новый ридер opencsv: new CSVReader( inputStream.newReader('UTF-8') )
@daggett Спасибо за помощь. Делюсь отработанным скриптом в качестве ответа.
Благодаря @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)
1. Вы не должны делать передачу внутри потока записи 2. Я рекомендую вам использовать процессор executegroovyscript