How to Parse Document and Get Output in CSV format with Salesforce Apex and PDF.co
In this step-by-step guide, we’ll observe steps on how to parse a PDF invoice document and get output in CSV format with Salesforce Apex and PDF.co. In the beginning, we’ll go through all the basic steps on salesforce integration. Later we’ll also see the code and demo video. Let’s get started!
Step 1: Create Remote Site Settings
Create remote site settings in the Salesforce Org like below.
Please note that the URL is “https://api.pdf.co”.
Step 2: Enter API Key
You should have an API class in your org with the key.
Step 3: Create an Apex Class in Salesforce
Create an apex class in Salesforce like below and paste the code there.
Once you login to the Salesforce org, you will see the screen like below and click on “Developer Console”
Create an apex class. For this, click on “Files” then “New” then “Apex Class”.
Write the class name “DocumentParserCSV” and click “Ok”. Now copy the DocumentParserCSV code in this file.
Similarly, create a new file with the name “DocumentParserCSVTest” and copy the code.
Step 4: Verify Code
To Verify the code, please open the execute Anonymous window and call the method below.
Then Click on “Execute”.
Step 5: See the Result
Now, You can see the result in the Debug Logs.
Step 6: Source Code Files:
API.cls
public class API {
public static String API_KEY = '********************************';
//Get Call
public static HttpResponse getCall(String endPointURL)
{
Http http = new Http();
HttpRequest request = new HttpRequest();
//Set the key in header.
request.setHeader('x-api-key', API_KEY);
//Set the URL to invoke
request.setEndpoint(endPointURL);
//Sets the type of method to be used for the HTTP request.
request.setMethod('GET');
/*
The timeout is the maximum time to wait for establishing the HTTP connection.
The same timeout is used for waiting for the request to start. When the request is executing,
such as retrieving or posting data, the connection is kept alive until the request finishes.
*/
request.setTimeout(60000);
HttpResponse response = http.send(request);
return response;
}
//Post Call
public static HttpResponse postCall(String endPointURL, String body, String contentType)
{
Http http = new Http();
HttpRequest request = new HttpRequest();
//Set the key in header.
request.setHeader('x-api-key', API_KEY);
//Set the URL to invoke
request.setEndpoint(endPointURL);
request.setHeader('Content-Type', contentType);
//Sets the type of method to be used for the HTTP request.
request.setMethod('POST');
//Sets the contents of the body for this request.
request.setBody(body);
/*
The timeout is the maximum time to wait for establishing the HTTP connection.
The same timeout is used for waiting for the request to start. When the request is executing,
such as retrieving or posting data, the connection is kept alive until the request finishes.
*/
request.setTimeout(60000);
HttpResponse response = http.send(request);
return response;
}
//PUT Call for Blob Body
public static HttpResponse putCall(String endPointURL, Blob body, String contentType)
{
Http http = new Http();
HttpRequest request = new HttpRequest();
//Set the key in header.
request.setHeader('x-api-key', API_KEY);
//Set the URL to invoke
request.setEndpoint(endPointURL);
request.setHeader('Content-Type', contentType);
//Sets the type of method to be used for the HTTP request.
request.setMethod('PUT');
//Sets the contents of the body for this request using a Blob.
request.setBodyAsBlob(body);
/*
The timeout is the maximum time to wait for establishing the HTTP connection.
The same timeout is used for waiting for the request to start. When the request is executing,
such as retrieving or posting data, the connection is kept alive until the request finishes.
*/
request.setTimeout(60000);
HttpResponse response = http.send(request);
return response;
}
}
APITest.cls
@isTest
public class APITest {
private testmethod static void getCallTest()
{
Test.setMock(HttpCalloutMock.class, new APITest.APIMock());
Test.StartTest();
HttpResponse resp = API.getCall('https://www.google.com/');
Test.stopTest();
System.assertNotEquals(null, resp);
}
private testmethod static void postCallTest()
{
Test.setMock(HttpCalloutMock.class, new APITest.APIMock());
Test.StartTest();
HTTPResponse res = API.postCall('https://www.google.com/', 'jsonPayload', 'application/json');
Test.stopTest();
System.assertNotEquals(null, res);
}
private testmethod static void putCallTest()
{
Test.setMock(HttpCalloutMock.class, new APITest.APIMock());
Test.StartTest();
HTTPResponse res = API.putCall('https://www.google.com/', Blob.valueOf('sourceFile'),'application/octet-stream');
Test.stopTest();
System.assertNotEquals(null, res);
}
public class APIMock implements HttpCalloutMock {
public HTTPResponse respond(HTTPRequest req) {
HttpResponse res = new HttpResponse();
String testBody = '{"presignedUrl":"https://pdf-temp-files.s3-us-west-2.amazonaws.com/0c72bf56341142ba83c8f98b47f14d62/test.pdf?X-Amz-Expires=900&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIZJDPLX6D7EHVCKA/20200302/us-west-2/s3/aws4_request&X-Amz-Date=20200302T143951Z&X-Amz-SignedHeaders=host&X-Amz-Signature=8650913644b6425ba8d52b78634698e5fc8970157d971a96f0279a64f4ba87fc","url":"https://pdf-temp-files.s3-us-west-2.amazonaws.com/0c72bf56341142ba83c8f98b47f14d62/test.pdf?X-Amz-Expires=3600&x-amz-security-token=FwoGZXIvYXdzEGgaDA9KaTOXRjkCdCqSTCKBAW9tReCLk1fVTZBH9exl9VIbP8Gfp1pE9hg6et94IBpNamOaBJ6%2B9Vsa5zxfiddlgA%2BxQ4tpd9gprFAxMzjN7UtjU%2B2gf%2FKbUKc2lfV18D2wXKd1FEhC6kkGJVL5UaoFONG%2Fw2jXfLxe3nCfquMEDo12XzcqIQtNFWXjKPWBkQEvmii4tfTyBTIot4Na%2BAUqkLshH0R7HVKlEBV8btqa0ctBjwzwpWkoU%2BF%2BCtnm8Lm4Eg%3D%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIA4NRRSZPHEGHTOA4W/20200302/us-west-2/s3/aws4_request&X-Amz-Date=20200302T143951Z&X-Amz-SignedHeaders=host;x-amz-security-token&X-Amz-Signature=243419ac4a9a315eebc2db72df0817de6a261a684482bbc897f0e7bb5d202bb9","error":false,"status":200,"name":"test.pdf","remainingCredits":98145}';
res.setHeader('Content-Type', 'application/json');
res.setBody(testBody);
res.setStatusCode(200);
return res;
}
}
}
DocumentParserCSV.cls
public class DocumentParserCSV {
public void startProcessing()
{
try
{
JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject();
gen.writeStringField('url', 'https://bytescout-com.s3-us-west-2.amazonaws.com/files/demo-files/cloud-api/document-parser/sample-invoice.pdf');
gen.writeStringField('templateId', '1');
gen.writeStringField('outputFormat', 'CSV');
gen.writeStringField('generateCsvHeaders', 'true');
gen.writeBooleanField('async', false);
gen.writeStringField('encrypt', 'false');
gen.writeStringField('inline', 'true');
gen.writeStringField('password', '');
gen.writeBooleanField('storeResult', false);
gen.writeEndObject();
// Convert dictionary of params to JSON
String jsonPayload = gen.getAsString();
String url = 'https://api.pdf.co/v1/pdf/documentparser';
HttpResponse response = API.postCall(url, jsonPayload, 'application/json');
Map<String, Object> json = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
if(response.getStatusCode() == 200)
{
if ((Boolean)json.get('error') == false)
{
// Get URL of generated PDF file
String jsonBody =(String)json.get('body');
SYstem.Debug(jsonBody);
}
}
else
{
System.debug('Error Response ' + response.getBody());
System.Debug(' Status ' + response.getStatus());
System.Debug(' Status Code' + response.getStatusCode());
System.Debug(' Response String' + response.toString());
}
}
catch (Exception ex)
{
String errorBody = 'Message: ' + ex.getMessage() + ' -- Cause: ' + ex.getCause() + ' -- Stacktrace: ' + ex.getStackTraceString();
System.Debug(errorBody);
}
}
}
DocumentParserCSVTest.cls
@isTest
private class DocumentParserCSVTest
{
private testmethod static void testDocumentParserCSV()
{
Test.setMock(HttpCalloutMock.class, new DocumentParserCSVTest.DocumentCreationMock());
DocumentParserCSV dc = new DocumentParserCSV();
Test.startTest();
dc.startProcessing();
Test.stopTest();
}
private testmethod static void testDocumentParserCSVError()
{
DocumentParserCSV dc = new DocumentParserCSV();
Test.startTest();
dc.startProcessing();
Test.stopTest();
}
public class DocumentCreationMock implements HttpCalloutMock {
public HTTPResponse respond(HTTPRequest req) {
HttpResponse res = new HttpResponse();
String testBody = '{"presignedUrl":"https://pdf-temp-files.s3-us-west-2.amazonaws.com/0c72bf56341142ba83c8f98b47f14d62/test.pdf?X-Amz-Expires=900&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIZJDPLX6D7EHVCKA/20200302/us-west-2/s3/aws4_request&X-Amz-Date=20200302T143951Z&X-Amz-SignedHeaders=host&X-Amz-Signature=8650913644b6425ba8d52b78634698e5fc8970157d971a96f0279a64f4ba87fc","url":"https://pdf-temp-files.s3-us-west-2.amazonaws.com/0c72bf56341142ba83c8f98b47f14d62/test.pdf?X-Amz-Expires=3600&x-amz-security-token=FwoGZXIvYXdzEGgaDA9KaTOXRjkCdCqSTCKBAW9tReCLk1fVTZBH9exl9VIbP8Gfp1pE9hg6et94IBpNamOaBJ6%2B9Vsa5zxfiddlgA%2BxQ4tpd9gprFAxMzjN7UtjU%2B2gf%2FKbUKc2lfV18D2wXKd1FEhC6kkGJVL5UaoFONG%2Fw2jXfLxe3nCfquMEDo12XzcqIQtNFWXjKPWBkQEvmii4tfTyBTIot4Na%2BAUqkLshH0R7HVKlEBV8btqa0ctBjwzwpWkoU%2BF%2BCtnm8Lm4Eg%3D%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIA4NRRSZPHEGHTOA4W/20200302/us-west-2/s3/aws4_request&X-Amz-Date=20200302T143951Z&X-Amz-SignedHeaders=host;x-amz-security-token&X-Amz-Signature=243419ac4a9a315eebc2db72df0817de6a261a684482bbc897f0e7bb5d202bb9","error":false,"status":200,"name":"test.pdf","remainingCredits":98145}';
res.setHeader('Content-Type', 'application/json');
res.setBody(testBody);
res.setStatusCode(200);
return res;
}
}
}