Document Information
Before your application merges data into a template, it often needs to know what the template expects: which merge fields it contains, which merge blocks repeat and how they are nested. The info endpoint of the DocumentProcessing Web API reads a document and returns this structure together with the document properties, such as the title and the author, without changing the document. A second endpoint lists the printers installed on the server, whose names you can pass as the formatting printer of a merge.
How Document Information Works
The endpoint is POST /documentprocessing/document/info:
| Part of the request | Content |
|---|---|
| Body | The document as a Base64 string in a JSON string, with the content type application/json |
| Response | A JSON object of the type DocumentInfo |
The response describes the document as a whole and its merge structure:
| Property | Content |
|---|---|
mergeFields | The merge fields of the document. Each has a name, and the formats and texts dateTimeFormat, numericFormat, preserveFormatting, text, textBefore and textAfter |
mergeBlocks | The merge blocks, each with its name, its own mergeFields and the mergeBlocks nested in it |
userDocumentProperties | The user-defined document properties, as names and values |
documentTitle, documentSubject, documentKeywords | The title, the subject and the keywords, documentKeywords as an array of strings |
author, creatorApplication | The author and the application that created the document |
creationDate, lastModificationDate | The dates of creation and of the last change |
A merge field is a placeholder that a merge replaces with a value from the data, and a merge block is a part of the template that the merge repeats for each record of an array, such as a table row per order item. The fields of a block are listed with the block, and each block lists only its own fields and blocks, not those of the blocks nested in it. Merging Templates shows how the structure maps to JSON data.
Every request needs an access token, as Authentication describes.
Read the Structure of a Template With curl
The following commands send template.docx to the info endpoint and print the merge fields and blocks:
DS=http://localhost:5000
TOKEN="<access_token>"
# Wrap the Base64 string of the template in a JSON string
base64 0 template.docx | jq . > template.json
curl POST "$DS/documentprocessing/document/info" \
"Authorization: Bearer $TOKEN" \
"Content-Type: application/json" \
@template.json \
info.json
jq '{mergeFields: [.mergeFields[].name], mergeBlocks}' info.json
The commands work as follows:
base64 -w 0encodes the file without line breaks, andjq -Rs .makes a JSON string of it. The body is this string alone, not an object around it.- The response is JSON, not Base64: info.json holds the
DocumentInfoobject as it is. - The last
jqcommand prints the names of the top-level merge fields and the merge blocks with their fields.
When DS Server runs on Linux, the Core build supports the document formats DOCX, HTML, PDF and XLSX only, as Limits on Linux lists. Send templates in one of these formats there.
Read the Structure of a Template With .NET
The package TXTextControl.DocumentServices.DocumentProcessing returns the response as a DocumentInfo object. The following console application prints the properties and the merge structure of template.docx, with nested blocks indented:
using TXTextControl.DocumentServices.DocumentProcessing;
using TXTextControl.DocumentServices.DocumentProcessing.OAuth;
var oauthSettings = new OAuthSettings("<client ID>", "<client secret>");
var documentProcessing = new DocumentProcessing("http://localhost:5000", oauthSettings);
byte[] template = File.ReadAllBytes("template.docx");
DocumentInfo info = await documentProcessing.Info(template);
Console.WriteLine($"Title: {info.DocumentTitle}, author: {info.Author}");
// Merge fields of the document
foreach (MergeField field in info.MergeFields)
{
Console.WriteLine($"Field: {field.Name}");
}
// Merge blocks with their fields and nested blocks
foreach (MergeBlock block in info.MergeBlocks)
{
PrintBlock(block, 0);
}
void PrintBlock(MergeBlock block, int level)
{
string indent = new string(' ', level * 2);
Console.WriteLine($"{indent}Block: {block.Name}");
foreach (MergeField field in block.MergeFields)
{
Console.WriteLine($"{indent} Field: {field.Name}");
}
foreach (MergeBlock nested in block.MergeBlocks)
{
PrintBlock(nested, level + 1);
}
}
The code works as follows:
- The
DocumentProcessingconstructor takes the service URL and the credentials of a security profile that allows the client credentials grant type, and requests an access token. Infosends the document as a byte array and returns aDocumentInfo. Its properties are those of the JSON response in Pascal case:MergeFields,MergeBlocks,DocumentTitle,Author,CreationDateand so on.MergeBlockhas aName, itsMergeFieldsand its nestedMergeBlocks, so the methodPrintBlockcalls itself for each nested block.
The classes are listed in the DocumentProcessing namespace of the .NET API.
Check a Template Before a Merge
The merge structure lets your application check a template before it merges it, for example a template that a user uploaded:
- Compare the field names with your data. Merge fields are named like the properties of a record. Collect the names from
mergeFieldsand from every block, and compare them with the keys of your JSON records. - Match blocks with arrays. A merge block is repeated for each element of a nested array, such as a block
OrderItemsfor the order items of a customer. Check that your data has an array for each block. - Build a form or a data mapping. The field names are the list of values a user has to provide, and
dateTimeFormatandnumericFormatshow how a field formats its value.
List the Printers Installed on the Server
A merge can format the document with the text dimensions and capabilities of a printer, the formatting printer. GET /documentprocessing/document/installedprinters returns the printers installed on the server that runs DS Server, as an array of PrinterInfo objects:
curl GET "$DS/documentprocessing/document/installedprinters" \
"Authorization: Bearer $TOKEN"
The merge settings of the merge and find-and-replace endpoints have a formattingPrinter property that takes the name of one of these printers, as the reference of POST /documentprocessing/document/merge lists. The endpoint was added in version 3.3.0; the changelog of that version names it document/printers, but DS Server 5.0.2 answers that address with 404 Not Found and serves the list at document/installedprinters.
In .NET, the method InstalledPrinters of the package returns the list as a PrinterInfo array, and the Name property of each element holds the name of the printer:
PrinterInfo[] printers = await documentProcessing.InstalledPrinters();
foreach (PrinterInfo printer in printers)
{
Console.WriteLine(printer.Name);
}
In version 5.0.0 of the package, a refused request of this method throws a plain Exception, not the ServiceRequestException of the other methods, and the exception has no status code. Errors and Status Codes shows how the other methods report errors.
Next Steps
- Merging Templates: merge the template with JSON data whose names match its fields and blocks.
- Find and Replace: replace text in a template that has no merge fields.
- PDF Form Fields: read the form fields of a PDF document.
- Errors and Status Codes: what a refused request means.