TX Text Control .NET Server

Document Properties

Topic

Title, author, subject and keywords, properties you define yourself and files embedded in PDF documents travel with the document that is open in the Document Editor, and your code reads and sets them. They help you find a document again in a document management system, or attach data such as the XML of an electronic invoice to a PDF document.

The examples extend the view of the ASP.NET Core tutorial. How documents are loaded and saved is described in Loading and Saving Documents.

What Document Properties Are

Besides its content, a document carries information about itself. TXTextControl.documentSettings returns a DocumentSettings object with this information for the document the user is working on:

PropertyContainsMethods
Title, author, subjectStringsgetDocumentTitle, setDocumentTitle, getAuthor, setAuthor, getDocumentSubject, setDocumentSubject
KeywordsAn array of stringsgetDocumentKeywords, setDocumentKeywords
Creator applicationThe application that created the documentgetCreatorApplication, setCreatorApplication
Creation dateA Unix timestampgetCreationDate, setCreationDate
Document base pathA file path used to find resources such as images or hypertext linksgetDocumentBasePath, setDocumentBasePath
User-defined propertiesAn object with properties you definegetUserDefinedDocumentProperties, setUserDefinedDocumentProperties
Embedded filesFiles attached to a PDF documentembeddedFiles

The properties are read with get methods, which pass the value to a callback, and changed with set methods. They are stored with the document when it is saved; your code doesn't have to pass them again. DocumentSettings was introduced in version 29.0.

Set and Read Properties

The following code sets the title, author, subject, keywords and two user-defined properties and logs them. Add it below the editor in Views/Home/Index.cshtml:

<input type="button" onclick="setProperties()" value="Set Properties" />
<input type="button" onclick="showProperties()" value="Show Properties" />

<script>
    function setProperties() {
        var settings = TXTextControl.documentSettings;

        settings.setDocumentTitle("Quarterly Report");
        settings.setAuthor("Tim Typer");
        settings.setDocumentSubject("Sales figures of the second quarter");
        settings.setDocumentKeywords(["sales", "report", "Q2"]);

        // Replaces all user-defined properties of the document
        settings.setUserDefinedDocumentProperties({
            department: "Sales",
            revision: 3
        });
    }

    function showProperties() {
        var settings = TXTextControl.documentSettings;

        settings.getDocumentTitle(function (title) {
            settings.getAuthor(function (author) {
                settings.getDocumentKeywords(function (keywords) {
                    console.log("Title: " + title);
                    console.log("Author: " + author);
                    // null if the document has no keywords
                    console.log("Keywords: " + (keywords === null ? "none" : keywords.join(", ")));
                });
            });
        });

        settings.getUserDefinedDocumentProperties(function (properties) {
            console.log(properties);
        });
    }
</script>

The code works as follows:

  • The set methods take the new value. The keywords are an array of strings.
  • setUserDefinedDocumentProperties takes an object whose properties become the user-defined properties of the document. Put property names that contain spaces in quotes, such as "review status": "open".
  • showProperties nests the get methods, because each passes its value to a callback. getDocumentKeywords passes null if the document has no keywords.

Click Set Properties and then Show Properties: the console shows the values you set.

Because the setter replaces all user-defined properties, read the existing ones first to add a single property:

function addProperty(name, value) {
  var settings = TXTextControl.documentSettings;

  settings.getUserDefinedDocumentProperties(function (properties) {
    properties = properties || {}; // no properties yet
    properties[name] = value;
    settings.setUserDefinedDocumentProperties(properties);
  });
}

On the server, the same properties are a UserDefinedPropertyDictionary, whose values are strings, Boolean values, integers or doubles and whose names have at most 255 characters. Use these types in the browser as well if the document is processed on the server.

Read the Properties of a Loaded Document

When your code loads a document with loadDocument, its callback receives LoadDocumentCallbackData with some of the properties, such as author, documentSubject, documentKeywords and creatorApplication:

// data contains a base64-encoded DOCX document
function loadAndShowProperties(data) {
  TXTextControl.loadDocument(TXTextControl.StreamType.WordprocessingML, data, function (result) {
    console.log("Author: " + result.author);
    console.log("Subject: " + result.documentSubject);
    console.log("Created by: " + result.creatorApplication);
  });
}

The callback data contains neither the title nor the user-defined properties. Read them with documentSettings inside the callback, once the document has been loaded.

Which Formats Store the Properties

  • User-defined properties are saved and loaded with the TX Text Control format, DOCX and RTF.
  • PDF documents store the title, author, subject, keywords, creation and modification date and creator application as metadata. Document Metadata covers the metadata of PDF documents on the server.
  • Save settings override the values of the document when it is saved. The SaveSettings object that saveDocument takes as its optional third parameter has properties such as documentTitle, author and documentKeywords.

Embed Files in PDF Documents

A PDF document can contain other files, for example the XML data of an invoice next to its visual representation. embeddedFiles returns the EmbeddedFileCollection of the document. Embedded files are only stored when the document is saved as PDF.

The following code embeds an XML file with a MIME type and a description, and lists the embedded files:

<input type="button" onclick="attachInvoiceData()" value="Attach Invoice Data" />
<input type="button" onclick="listEmbeddedFiles()" value="List Embedded Files" />

<script>
    function attachInvoiceData() {
        var files = TXTextControl.documentSettings.embeddedFiles;
        var xml = "<invoice><number>1001</number><total>249.50</total></invoice>";

        files.addTextFile("invoice.xml", xml, null, function () {
            // Find the new file by its name to complete its settings
            files.forEach(function (file) {
                file.getFileName(function (name) {
                    if (name === "invoice.xml") {
                        file.setMIMEType("application/xml");
                        file.setDescription("Invoice data");
                    }
                });
            });
        });
    }

    function listEmbeddedFiles() {
        TXTextControl.documentSettings.embeddedFiles.forEach(function (file, index, count) {
            file.getFileName(function (name) {
                file.getMIMEType(function (mimeType) {
                    console.log((index + 1) + " of " + count + ": " + name + " (" + mimeType + ")");
                });
            });
        });
    }
</script>
  • addTextFile takes the file name, the content as a string and optional XMP metadata for the file, which can be null. addBinaryFile takes the content as a base64-encoded string instead.
  • Each EmbeddedFile has a file name and data that can't be changed, and a description, MIME type and dates that can. Without a MIME type, application/octet-stream is used.
  • removeElementAt removes a file from the collection by its index.

Save the document with TXTextControl.StreamType.AdobePDF to store the files. Electronic invoices such as ZUGFeRD and XRechnung are PDF/A-3 documents, a format the JavaScript StreamType doesn't contain: such documents are created on the server, where the relationship of each file (setRelationship, for PDF/A only) and its MIME type are required. The blog article Why Defining MIME Types for PDF/A Attachments Is Essential explains why, and Attachments covers attachments on the server.

Next Steps