我正在尝试做相当简单的事情,并从传入的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日志中看到输出(如果出错,它将向处理器发布公告,并且如果您将鼠标悬停,则会看到此消息处理器的右上角(如果存在公告,则为红色正方形)。

10-08 17:47