Quickstart: SDK voor Java-clientbibliotheek v3.0 | Voorbeeld

Notitie

Form Recognizer versie 3.0 is momenteel beschikbaar als openbare preview. Sommige functies worden mogelijk niet ondersteund of hebben beperkte mogelijkheden.

Referentiedocumentatie | Broncode van bibliotheek | Pakket (Maven) | Voorbeelden

Aan de slag met Azure Form Recognizer de Java-programmeertaal. Azure Form Recognizer is een cloudgebaseerde, door Azure toegepaste AI-service die gebruikmaakt van machine learning voor het extraheren en analyseren van formuliervelden, tekst en tabellen uit uw documenten. U kunt eenvoudig de Form Recognizer aanroepen door onze clientbibliotheek-SDK's te integreren in uw werkstromen en toepassingen. U wordt aangeraden de gratis service te gebruiken wanneer u de technologie leert. Houd er rekening mee dat het aantal gratis pagina's beperkt is tot 500 per maand.

Ga naar onze overzichtspagina Form Recognizer meer informatie over de functies en ontwikkelingsopties.

In deze quickstart gebruikt u de volgende functies om gegevens en waarden uit formulieren en documenten te analyseren en te extraheren:

  • 🆕 document : tekst,tabellen, structuur, sleutel-waardeparen en benoemde entiteiten analyseren en extraheren.

  • Indeling:tabellen, lijnen, woorden en selectiemarkeringen zoals keuzerondjes en selectievakjes in formulierendocumenten analyseren en extraheren, zonder dat u een model hoeft te trainen.

  • Vooraf gebouwde factuur Algemene velden analyseren en extraheren uit facturen met behulp van een vooraf getraind factuurmodel.

Vereisten

Tip

Maak een Cognitive Services als u van plan bent toegang te krijgen tot meerdere cognitieve services onder één eindpunt/sleutel. Als Form Recognizer alleen toegang hebt, maakt u een Form Recognizer resource. Houd er rekening mee dat u een resource voor één service nodig hebt als u van plan bent om Azure Active Directory gebruiken.

  • Nadat uw resource is geïmplementeerd, klikt u op Ga naar resource. U hebt de sleutel en het eindpunt nodig van de resource die u maakt om uw toepassing te verbinden met Form Recognizer API. U plakt uw sleutel en eindpunt later in de onderstaande code in de quickstart:

    Schermopname: sleutels en eindpuntlocatie in de Azure Portal.

Instellen

Een nieuw Gradle-project maken

Maak in een consolevenster (zoals cmd, PowerShell of Bash) een nieuwe map voor uw app met de naam form-recognizer-app en navigeer er naartoe.

mkdir form-recognizer-app && form-recognizer-app

Voer de opdracht gradle init uit vanuit uw werkmap. Met deze opdracht maakt u essentiële buildbestanden voor Gradle, inclusief build.gradle.kts, dat tijdens runtime wordt gebruikt om de toepassing te maken en te configureren.

gradle init --type basic
  1. Wanneer u wordt gevraagd om een DSL te kiezen, selecteert u Kotlin.

  2. Accepteer de standaardprojectnaam (form-recognizer-app)

De clientbibliotheek installeren

Deze quickstart maakt gebruik van de Gradle-afhankelijkheidsmanager. U vindt de clientbibliotheek en informatie voor andere afhankelijkheidsbeheerders in de Maven Central Repository.

Zorg ervoor dat u in het bestand build.gradle.kts de clientbibliotheek opneemt als een implementation-instructie, samen met de vereiste invoegtoepassen en instellingen.

plugins {
    java
    application
}
application {
    mainClass.set("FormRecognizer")
}
repositories {
    mavenCentral()
}
dependencies {
    implementation(group = "com.azure", name = "azure-ai-formrecognizer", version = "4.0.0-beta.1")
}

Een Java-bestand maken

Voer de volgende opdracht uit vanuit uw werkmap:

mkdir -p src/main/java

U maakt de volgende mapstructuur:

Schermopname: Java-mapstructuur

Navigeer naar de nieuwe map en maak een bestand met de naam FormRecognizer.java (gemaakt tijdens de gradle init opdracht). Open deze in uw favoriete editor of IDE en voeg de volgende pakketdeclaratie en -instructies import toe:

package com.azure.ai.formrecognizer;

import com.azure.ai.formrecognizer.models.AnalyzeDocumentOptions;
import com.azure.ai.formrecognizer.models.AnalyzedDocument;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.http.HttpPipeline;
import com.azure.core.http.HttpPipelineBuilder;
import com.azure.core.util.Context;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.Arrays;

Selecteer een codevoorbeeld om de hoofdmethode van uw toepassing te kopiëren en plakken:

Belangrijk

Vergeet niet de sleutel uit uw code te verwijderen wanneer u klaar bent, en plaats deze sleutel nooit in het openbaar. Gebruik voor productie beveiligde methoden om uw referenties op te slaan en te openen. Zie het artikel Cognitive Services Beveiliging voor meer informatie.

Probeer het: Algemeen documentmodel

  • Voor dit voorbeeld hebt u een formulierdocumentbestand op een URI nodig. U kunt ons voorbeeldformulierdocument gebruiken voor deze quickstart.
  • Als u een bepaald bestand op een URI wilt analyseren, gebruikt u de beginAnalyzeDocumentFromUrl methode en door te geven als de prebuilt-document model-id. De geretourneerde waarde is AnalyzeResult een object met gegevens over het ingediende document.
  • We hebben de bestands-URI-waarde toegevoegd aan de documentUrl variabele in de main-methode.
  • Ter vereenvoudiging worden alle entiteitsvelden die de service retourneert, hier niet weergegeven. Zie de pagina Algemeen documentconcept voor een overzicht van alle ondersteunde velden en bijbehorende typen.

Werk de FormRecognizer-klasse van uw toepassing bij met de volgende code (werk de sleutel- en eindpuntvariabelen bij met waarden uit uw Form Recognizer-exemplaar in de Azure Portal):

public class FormRecognizer {

    static final String key = "PASTE_YOUR_FORM_RECOGNIZER_SUBSCRIPTION_KEY_HERE";
    static final String endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE";

    public static void main(String[] args) {

        DocumentAnalysisClient documentAnalysisClient = new DocumentAnalysisClientBuilder()
            .credential(new AzureKeyCredential("{key}"))
            .endpoint("{endpoint}")
            .buildClient();

        String documentUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf";
        String modelId = "prebuilt-document";
        SyncPoller < DocumentOperationResult, AnalyzeResult > analyzeDocumentPoller =
            documentAnalysisClient.beginAnalyzeDocumentFromUrl(modelId, documentUrl);

        AnalyzeResult analyzeResult = analyzeDocumentPoller.getFinalResult();

        for (int i = 0; i < analyzeResult.getDocuments().size(); i++) {
            final AnalyzedDocument analyzedDocument = analyzeResult.getDocuments().get(i);
            System.out.printf("----------- Analyzing document %d -----------%n", i);
            System.out.printf("Analyzed document has doc type %s with confidence : %.2f%n",
                analyzedDocument.getDocType(), analyzedDocument.getConfidence());
        }

        analyzeResult.getPages().forEach(documentPage - > {
            System.out.printf("Page has width: %.2f and height: %.2f, measured with unit: %s%n",
                documentPage.getWidth(),
                documentPage.getHeight(),
                documentPage.getUnit());

            // lines
            documentPage.getLines().forEach(documentLine - >
                System.out.printf("Line %s is within a bounding box %s.%n",
                    documentLine.getContent(),
                    documentLine.getBoundingBox().toString()));

            // words
            documentPage.getWords().forEach(documentWord - >
                System.out.printf("Word %s has a confidence score of %.2f%n.",
                    documentWord.getContent(),
                    documentWord.getConfidence()));
        });

        // tables
        List < DocumentTable > tables = analyzeResult.getTables();
        for (int i = 0; i < tables.size(); i++) {
            DocumentTable documentTable = tables.get(i);
            System.out.printf("Table %d has %d rows and %d columns.%n", i, documentTable.getRowCount(),
                documentTable.getColumnCount());
            documentTable.getCells().forEach(documentTableCell - > {
                System.out.printf("Cell '%s', has row index %d and column index %d.%n",
                    documentTableCell.getContent(),
                    documentTableCell.getRowIndex(), documentTableCell.getColumnIndex());
            });
            System.out.println();
        }

        // Entities
        analyzeResult.getEntities().forEach(documentEntity - > {
            System.out.printf("Entity category : %s, sub-category %s%n: ",
                documentEntity.getCategory(), documentEntity.getSubCategory());
            System.out.printf("Entity content: %s%n: ", documentEntity.getContent());
            System.out.printf("Entity confidence: %.2f%n", documentEntity.getConfidence());
        });

        // Key-value
        analyzeResult.getKeyValuePairs().forEach(documentKeyValuePair - > {
            System.out.printf("Key content: %s%n", documentKeyValuePair.getKey().getContent());
            System.out.printf("Key content bounding region: %s%n",
                documentKeyValuePair.getKey().getBoundingRegions().toString());

            System.out.printf("Value content: %s%n", documentKeyValuePair.getValue().getContent());
            System.out.printf("Value content bounding region: %s%n", documentKeyValuePair.getValue().getBoundingRegions().toString());
        });
        Build a custom document analysis model
        In 3. x.x, creating a custom model required specifying useTrainingLabels to indicate whether to use labeled data when creating the custom model with the beginTraining method.
        In 4. x.x, we introduced the new general document model(prebuilt - document) to replace the train without labels functionality from 3. x.x which extracts entities, key - value pairs, and layout from a document with the beginBuildModel method.In 4. x.x the beginBuildModel always returns labeled data otherwise.
        Train a custom model using 3. x.x beginTraining:

            String trainingFilesUrl = "{SAS_URL_of_your_container_in_blob_storage}";
        SyncPoller < FormRecognizerOperationResult, CustomFormModel > trainingPoller =
            formTrainingClient.beginTraining(trainingFilesUrl,
                false,
                new TrainingOptions()
                .setModelName("my model trained without labels"),
                Context.NONE);

        CustomFormModel customFormModel = trainingPoller.getFinalResult();

        // Model Info
        System.out.printf("Model Id: %s%n", customFormModel.getModelId());
        System.out.printf("Model name given by user: %s%n", customFormModel.getModelName());
        System.out.printf("Model Status: %s%n", customFormModel.getModelStatus());
        System.out.printf("Training started on: %s%n", customFormModel.getTrainingStartedOn());
        System.out.printf("Training completed on: %s%n%n", customFormModel.getTrainingCompletedOn());

        System.out.println("Recognized Fields:");
        // looping through the subModels, which contains the fields they were trained on
        // Since the given training documents are unlabeled we still group them but, they do not have a label.
        customFormModel.getSubmodels().forEach(customFormSubmodel - > {
            System.out.printf("Submodel Id: %s%n: ", customFormSubmodel.getModelId());
            // Since the training data is unlabeled, we are unable to return the accuracy of this model
            customFormSubmodel.getFields().forEach((field, customFormModelField) - >
                System.out.printf("Field: %s Field Label: %s%n",
                    field, customFormModelField.getLabel()));
        });

        System.out.println();
        customFormModel.getTrainingDocuments().forEach(trainingDocumentInfo - > {
            System.out.printf("Document name: %s%n", trainingDocumentInfo.getName());
            System.out.printf("Document status: %s%n", trainingDocumentInfo.getStatus());
            System.out.printf("Document page count: %d%n", trainingDocumentInfo.getPageCount());
            if (!trainingDocumentInfo.getErrors().isEmpty()) {
                System.out.println("Document Errors:");
                trainingDocumentInfo.getErrors().forEach(formRecognizerError - >
                    System.out.printf("Error code %s, Error message: %s%n", formRecognizerError.getErrorCode(),
                        formRecognizerError.getMessage()));
            }
        });
    }

Probeer het: Indelingsmodel

Extraheren van tekst, selectiemarkeringen, tekststijlen en tabelstructuren, samen met de coördinaten van de begrenzingsregio uit documenten.

  • Voor dit voorbeeld hebt u een formulierdocumentbestand op een URI nodig. U kunt ons voorbeeldformulierdocument gebruiken voor deze quickstart.
  • Als u een bepaald bestand op een URI wilt analyseren, gebruikt u de beginAnalyzeDocumentFromUrl methode en door te geven als de prebuilt-layout model-id. De geretourneerde waarde is AnalyzeResult een object met gegevens over het ingediende document.
  • We hebben de bestands-URI-waarde toegevoegd aan de documentUrl variabele in de main-methode.

Werk de FormRecognizer-klasse van uw toepassing bij met de volgende code (werk de sleutel- en eindpuntvariabelen bij met waarden uit uw Form Recognizer-exemplaar in de Azure Portal):

public class FormRecognizer {

    static final String key = "PASTE_YOUR_FORM_RECOGNIZER_SUBSCRIPTION_KEY_HERE";
    static final String endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE";

    public static void main(String[] args) {

        DocumentAnalysisClient documentAnalysisClient = new DocumentAnalysisClientBuilder()
            .credential(new AzureKeyCredential("{key}"))
            .endpoint("{endpoint}")
            .buildClient();

        String documentUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf"
        String modelId = "prebuilt-layout";

        SyncPoller < DocumentOperationResult, AnalyzeResult > analyzeLayoutResultPoller =
            documentAnalysisClient.beginAnalyzeDocument(modelId, documentUrl);

        AnalyzeResult analyzeLayoutResult = analyzeLayoutResultPoller.getFinalResult();

        // pages
        analyzeLayoutResult.getPages().forEach(documentPage - > {
            System.out.printf("Page has width: %.2f and height: %.2f, measured with unit: %s%n",
                documentPage.getWidth(),
                documentPage.getHeight(),
                documentPage.getUnit());

            // lines
            documentPage.getLines().forEach(documentLine - >
                System.out.printf("Line %s is within a bounding box %s.%n",
                    documentLine.getContent(),
                    documentLine.getBoundingBox().toString()));

            // selection marks
            documentPage.getSelectionMarks().forEach(documentSelectionMark - >
                System.out.printf("Selection mark is %s and is within a bounding box %s with confidence %.2f.%n",
                    documentSelectionMark.getState().toString(),
                    documentSelectionMark.getBoundingBox().toString(),
                    documentSelectionMark.getConfidence()));
        });

        // tables
        List < DocumentTable > tables = analyzeLayoutResult.getTables();
        for (int i = 0; i < tables.size(); i++) {
            DocumentTable documentTable = tables.get(i);
            System.out.printf("Table %d has %d rows and %d columns.%n", i, documentTable.getRowCount(),
                documentTable.getColumnCount());
            documentTable.getCells().forEach(documentTableCell - > {
                System.out.printf("Cell '%s', has row index %d and column index %d.%n", documentTableCell.getContent(),
                    documentTableCell.getRowIndex(), documentTableCell.getColumnIndex());
            });
            System.out.println();
        }
    }

Probeer het: Vooraf gebouwd model

In dit voorbeeld wordt gedemonstreerd hoe u gegevens uit bepaalde typen algemene documenten met vooraf getrainde modellen kunt analyseren met behulp van een factuur als voorbeeld.

  • In dit voorbeeld analyseren we een factuurdocument met behulp van een vooraf gebouwd model. U kunt ons voorbeeld van een factuurdocument gebruiken voor deze quickstart.
  • Als u een bepaald bestand op een URI wilt analyseren, gebruikt u de beginAnalyzeDocumentFromUrl methode en door te geven als de prebuilt-invoice model-id. De geretourneerde waarde is AnalyzeResult een object met gegevens over het ingediende document.
  • We hebben de bestands-URI-waarde toegevoegd aan de invoiceUrl variabele in de main-methode.
  • Ter vereenvoudiging worden alle sleutel-waardeparen die de service retourneert, hier niet weergegeven. Zie onze pagina Factuurconcept voor een overzicht van alle ondersteunde velden en bijbehorende typen.

De vooraf gebouwde model-id voor facturen kiezen

U bent niet beperkt tot facturen: er zijn verschillende vooraf gebouwde modellen waaruit u kunt kiezen, die elk een eigen set ondersteunde velden hebben. Het model dat voor de analysebewerking moet worden gebruikt, is afhankelijk van het type document dat moet worden geanalyseerd. Dit zijn de model-ID's voor de vooraf gebouwde modellen die momenteel worden ondersteund door de Form Recognizer service:

Werk de FormRecognizer-klasse van uw toepassing bij met de volgende code (werk de sleutel- en eindpuntvariabelen bij met waarden uit uw Form Recognizer-exemplaar in de Azure Portal):


public class FormRecognizer {

    static final String key = "PASTE_YOUR_FORM_RECOGNIZER_SUBSCRIPTION_KEY_HERE";
    static final String endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE";

    public static void main(String[] args) {

        DocumentAnalysisClient documentAnalysisClient = new DocumentAnalysisClientBuilder()
            .credential(new AzureKeyCredential("{key}"))
            .endpoint("{endpoint}")
            .buildClient();

        String invoiceUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-invoice.pdf"
        String modelId = "prebuilt-invoice";

        PollerFlux < DocumentOperationResult, AnalyzeResult > analyzeInvoicePoller = client.beginAnalyzeDocumentFromUrl("prebuilt-invoice", invoiceUrl);

        Mono < AnalyzeResult > analyzeInvoiceResultMono = analyzeInvoicePoller
            .last()
            .flatMap(pollResponse - > {
                if (pollResponse.getStatus().isComplete()) {
                    System.out.println("Polling completed successfully");
                    return pollResponse.getFinalResult();
                } else {
                    return Mono.error(new RuntimeException("Polling completed unsuccessfully with status:" +
                        pollResponse.getStatus()));
                }
            });

        analyzeInvoiceResultMono.subscribe(analyzeInvoiceResult - > {
            for (int i = 0; i < analyzeInvoiceResult.getDocuments().size(); i++) {
                AnalyzedDocument analyzedInvoice = analyzeInvoiceResult.getDocuments().get(i);
                Map < String, DocumentField > invoiceFields = analyzedInvoice.getFields();
                System.out.printf("----------- Analyzing invoice  %d -----------%n", i);
                DocumentField vendorNameField = invoiceFields.get("VendorName");
                if (vendorNameField != null) {
                    if (DocumentFieldType.STRING == vendorNameField.getType()) {
                        String merchantName = vendorNameField.getValueString();
                        System.out.printf("Vendor Name: %s, confidence: %.2f%n",
                            merchantName, vendorNameField.getConfidence());
                    }
                }

                DocumentField vendorAddressField = invoiceFields.get("VendorAddress");
                if (vendorAddressField != null) {
                    if (DocumentFieldType.STRING == vendorAddressField.getType()) {
                        String merchantAddress = vendorAddressField.getValueString();
                        System.out.printf("Vendor address: %s, confidence: %.2f%n",
                            merchantAddress, vendorAddressField.getConfidence());
                    }
                }

                DocumentField customerNameField = invoiceFields.get("CustomerName");
                if (customerNameField != null) {
                    if (DocumentFieldType.STRING == customerNameField.getType()) {
                        String merchantAddress = customerNameField.getValueString();
                        System.out.printf("Customer Name: %s, confidence: %.2f%n",
                            merchantAddress, customerNameField.getConfidence());
                    }
                }

                DocumentField customerAddressRecipientField = invoiceFields.get("CustomerAddressRecipient");
                if (customerAddressRecipientField != null) {
                    if (DocumentFieldType.STRING == customerAddressRecipientField.getType()) {
                        String customerAddr = customerAddressRecipientField.getValueString();
                        System.out.printf("Customer Address Recipient: %s, confidence: %.2f%n",
                            customerAddr, customerAddressRecipientField.getConfidence());
                    }
                }

                DocumentField invoiceIdField = invoiceFields.get("InvoiceId");
                if (invoiceIdField != null) {
                    if (DocumentFieldType.STRING == invoiceIdField.getType()) {
                        String invoiceId = invoiceIdField.getValueString();
                        System.out.printf("Invoice ID: %s, confidence: %.2f%n",
                            invoiceId, invoiceIdField.getConfidence());
                    }
                }

                DocumentField invoiceDateField = invoiceFields.get("InvoiceDate");
                if (customerNameField != null) {
                    if (DocumentFieldType.DATE == invoiceDateField.getType()) {
                        LocalDate invoiceDate = invoiceDateField.getValueDate();
                        System.out.printf("Invoice Date: %s, confidence: %.2f%n",
                            invoiceDate, invoiceDateField.getConfidence());
                    }
                }

                DocumentField invoiceTotalField = invoiceFields.get("InvoiceTotal");
                if (customerAddressRecipientField != null) {
                    if (DocumentFieldType.FLOAT == invoiceTotalField.getType()) {
                        Float invoiceTotal = invoiceTotalField.getValueFloat();
                        System.out.printf("Invoice Total: %.2f, confidence: %.2f%n",
                            invoiceTotal, invoiceTotalField.getConfidence());
                    }
                }

                DocumentField invoiceItemsField = invoiceFields.get("Items");
                if (invoiceItemsField != null) {
                    System.out.printf("Invoice Items: %n");
                    if (DocumentFieldType.LIST == invoiceItemsField.getType()) {
                        List < DocumentField > invoiceItems = invoiceItemsField.getValueList();
                        invoiceItems.stream()
                            .filter(invoiceItem - > DocumentFieldType.MAP == invoiceItem.getType())
                            .map(formField - > formField.getValueMap())
                            .forEach(formFieldMap - > formFieldMap.forEach((key, formField) - > {
                                // See a full list of fields found on an invoice here:
                                // https://aka.ms/formrecognizer/invoicefields
                                if ("Description".equals(key)) {
                                    if (DocumentFieldType.STRING == formField.getType()) {
                                        String name = formField.getValueString();
                                        System.out.printf("Description: %s, confidence: %.2fs%n",
                                            name, formField.getConfidence());
                                    }
                                }
                                if ("Quantity".equals(key)) {
                                    if (DocumentFieldType.FLOAT == formField.getType()) {
                                        Float quantity = formField.getValueFloat();
                                        System.out.printf("Quantity: %f, confidence: %.2f%n",
                                            quantity, formField.getConfidence());
                                    }
                                }
                                if ("UnitPrice".equals(key)) {
                                    if (DocumentFieldType.FLOAT == formField.getType()) {
                                        Float unitPrice = formField.getValueFloat();
                                        System.out.printf("Unit Price: %f, confidence: %.2f%n",
                                            unitPrice, formField.getConfidence());
                                    }
                                }
                                if ("ProductCode".equals(key)) {
                                    if (DocumentFieldType.FLOAT == formField.getType()) {
                                        Float productCode = formField.getValueFloat();
                                        System.out.printf("Product Code: %f, confidence: %.2f%n",
                                            productCode, formField.getConfidence());
                                    }
                                }
                            }));
                    }
                }
            }
        });
    }
}

Uw toepassing bouwen en uitvoeren

Ga terug naar de hoofdmap van het project:form-recognizer-app.

  1. Bouw uw toepassing met de build opdracht :
gradle build
  1. Voer uw toepassing uit met de run opdracht :
gradle run

Gefeliciteerd In deze quickstart hebt u de java Form Recognizer-SDK gebruikt om verschillende formulieren en documenten op verschillende manieren te analyseren. Bekijk vervolgens de referentiedocumentatie voor meer informatie over Form Recognizer API.

Volgende stappen