我正在尝试做相当简单的事情,并从传入的FlowFile中读取i9 PDF表单,将其中的名字和姓氏解析为JSON,然后将JSON输出到传出的FlowFile。
我没有找到有关此操作的官方文档,但是有人写了几个cookbooks on doing things in several scripting languages in NiFi here.似乎很简单,我很确定自己正在写那里的内容,但是我什至不确定PDF是否正在读完。它将每次简单地将未修改的PDF传递给REL_SUCCESS。
Link to sample PDF
import java.nio.charset.StandardCharsets
import org.apache.pdfbox.io.IOUtils
import org.apache.pdfbox.pdmodel.PDDocument
import org.apache.pdfbox.util.PDFTextStripperByArea
import java.awt.Rectangle
import org.apache.pdfbox.pdmodel.PDPage
import com.google.gson.Gson
import java.nio.charset.StandardCharsets
def flowFile = session.get()
flowFile = session.write(flowFile, { inputStream, outputStream ->
try {
//Load Flowfile contents
PDDocument document = PDDocument.load(inputStream)
PDFTextStripperByArea stripper = new PDFTextStripperByArea()
//Get the first page
List<PDPage> allPages = document.getDocumentCatalog().getAllPages()
PDPage page = allPages.get(0)
//Define the areas to search and add them as search regions
stripper = new PDFTextStripperByArea()
Rectangle lname = new Rectangle(25, 226, 240, 15)
stripper.addRegion("lname", lname)
Rectangle fname = new Rectangle(276, 226, 240, 15)
stripper.addRegion("fname", fname)
//Load the results into a JSON
def boxMap = [:]
stripper.setSortByPosition(true)
stripper.extractRegions(page)
regions = stripper.getRegions()
for (String region : regions) {
String box = stripper.getTextForRegion(region)
boxMap.put(region, box)
}
Gson gson = new Gson()
//Remove random noise from the output
json = gson.toJson(boxMap, LinkedHashMap.class)
json = json.replace('\\n', '')
json = json.replace('\\r', '')
json = json.replace(',"', ',\n"')
//Overwrite flowfile contents with JSON
outputStream.write(json.getBytes(StandardCharsets.UTF_8))
} catch (Exception e){
System.out.println(e.getMessage())
session.transfer(flowFile, REL_FAILURE)
}
} as StreamCallback)
session.transfer(flowFile, REL_SUCCESS)
编辑:
可以通过将txt文件放入其中来确认flowFile对象是否已正确读取。因此问题似乎是inputStream从未移交给PDDocument或发生了什么事情。我编辑了代码,尝试首先将其读取到File对象中,但这导致了错误:
FlowFileHandlingException: null is not known in this session
编辑编辑:
通过移动我的try / catch来解决。我似乎不明白它是如何工作的,上面的代码已经过编辑并且可以正常工作。
最佳答案
session.get
可以返回null,因此肯定在if(!flowFile) return
之后添加一行。还将try / catch放在session.write
之外,这样就可以将session.transfer(flowFile,REL_SUCCESS)放在session.write之后(在try里面),并且catch
可以转换为失败。
我也无法从代码中得知PDFTextStripperByArea如何从传入文档中获取信息。看起来所有文档内容都在尝试之内,因此PDFTextStripper将无法使用(并且不会传入)。
这些都没有解释为什么您要在success
关系上获得原始流文件,但是也许我看不到有什么可以通过上述更改而神奇地解决的:)
另外,如果您使用log.info()
或log.error()
而不是System.out.println,您将在NiFi日志中看到输出(如果出错,它将向处理器发布公告,并且如果您将鼠标悬停,则会看到此消息处理器的右上角(如果存在公告,则为红色正方形)。