Pesquisar

Discussão (0)1
Entre ou crie uma conta para continuar
Artigo
· Jul. 26 8min de leitura

Creating advanced Word documents with IRIS

Word documents are widely used in the market. Users frequently create contracts, memos, resumes, reports, analyses, and other documents that may require data from or captured by InterSystems IRIS. However, IRIS does not have an API, SDK, library, or adapter for this. This limitation no longer exists. 

The new Open Exchange library iris4word (https://openexchange.intersystems.com/package/iris4word) delivers an ObjectScript SDK where the developer passes any %DynamicObject as a parameter, a Word file template and then receives a ready document, with the structure and formatting defined in its template.


To use iris4word

This article will use a REST API to get the content, but it is possible query database also. To install the iris4word and the sample using it, proceed with these tasks:

  1. If you use IPM/ZPM: zpm:USER>install iris4word
  2. If you use Docker: 
    1. git clone https://github.com/yurimarx/iris4word.git
    2. docker-compose up -d --build
  3. Open the Postman (to execute the REST API sample)
  4. Import the sample collection from (https://raw.githubusercontent.com/yurimarx/iris4word/refs/heads/master/iris4word.postman_collection.json): 
  5. Upload the file template template.docx (in the sample/template.docx path of this repository or from https://raw.githubusercontent.com/yurimarx/iris4word/refs/heads/master/sample/template.docx). To upload, fill the file field into the Body tab: 
  6.  The upload process will send the template to the server to be used by the iris4word.
  7. Open the 2. Download Word Document and copy and past to the body this JSON content: 
    {
      "company": {
        "name": "ACM Ltda.",
        "address": "Main Street, 123",
        "city": "New York",
        "state": "NY"
      },
      "projects": [
        {
          "name": "System Development X",
          "beginDate": "2024-01-01",
          "endDate": "2024-06-06",
          "team": [
            {"name": "John Star", "role": "Senior Developer"},
            {"name": "Marie Loo", "role": "BDM"}
          ],
          "tasks": [
            {"description": "Requirements", "status": "Done"},
            {"description": "Development", "status": "Doing"}
          ]
        },
        {
          "name": "ERP Development Y",
          "beginDate": "2024-03-03",
          "endDate": "2025-12-12",
          "team": [
            {"name": "Peter Rogers", "role": "Project Manager"},
            {"name": "Robert Plant", "role": "ERP Specialist"}
          ],
          "tasks": [
            {"description": "ERP configuration", "status": "Done"},
            {"description": "User training", "status": "Doing"}
          ]
        }
      ],
      "principalContact": {
        "name": "Carlos Olivera",
        "email": "carlos.olivera@company.com",
        "phone": "+1 555 555-555"
      }
    }
     
  8. On the Send button, select the option Send and Download:
  9. See the results:
  10. Compare the JSON content with the template.docx and see the marks and tags used.

Behind the Scenes

It's very easy, with the template file saved into /tmp/template.docx, just call it:

ClassMethod DownloadDoc(template As %String) As %Status
{
    Set tUUID = $System.Util.CreateGUID() 
    Set filePath = "/tmp/"_tUUID_".docx"
    Set jsonContentString = {}.%FromJSON(%request.Content)
    Set sc = ##class(dc.iris4word.WordUtil).GenerateWordFileFromJSON(jsonContentString.%ToJSON(), "/tmp/"_template_".docx", filePath)

    Set %response.NoCharSetConvert=1
    Set %response.Headers("Access-Control-Allow-Origin")="*"
    Do %response.SetHeader("Content-Type","application/vnd.openxmlformats-officedocument.wordprocessingml.document")
    Do %response.SetHeader("Content-Disposition","attachment;filename="""_tUUID_".docx"_"""")
    
    Set stream=##class(%Stream.FileBinary).%New()
    Set sc=stream.LinkToFile(filePath)
    Do stream.OutputToDevice()
    
    Return sc
}

O ClassMethod ##class(dc.iris4word.WordUtil).GenerateWordFileFromJSON recebe os dados na forma de um %DynamicObject, the word template path and the file path where the final word document must be created. Now you have a word file to send to the user as response. Very easy!!

The Template language

The iris4word delivers to you a flexible template language to compose dynamic word documents using the Microsoft Word editor.

Text tag

The text tag is the most basic tag type in the Word template. {{name}} will be replaced by the value of key name in the data model. If the key is not exist, the tag will be cleared(The program can configure whether to keep the tag or throw an exception).

Template:

{{name}} always said life was like a box of {{thing}}.

Output:

Mama always said life was like a box of chocolates.

Picture tag

The image tag starts with @, for example, {{@logo}} will look for the value with the key of logo in the data model, and then replace the tag with the image. The data corresponding to the image tag can be a simple URL or Path string, or a structure containing the width and height of the image.

Template:

Fruit Logo:
watermelon {{@watermelon}}
lemon {{@lemon}}
banana {{@banana}}
Output:

Fruit Logo:
watermelon 🍉
lemon 🍋
banana 🍌

Numbering

The list tag corresponds to Word's symbol list or numbered list, starting with *, such as {{*number}}.

Template:

{{*list}}
Output:

● Plug-in grammar
● Supports word text, pictures, table...
● Templates, not just templates, but also style templates

Sections

A section is composed of two tags before and after, the start tag is identified by ?, and the end tag is identified by /, such as {{?section}} as the start tag of the sections block, {{/section} } is the end tag, and section is the name of this section.

Sections are very useful when processing a series of document elements. Document elements (text, pictures, tables, etc.) located in a section can be rendered zero, one or N times, depending on the value of the section.

False Values or Empty collection

If the value of the section is null, false or an empty collection, all document elements located in the section will not be displayed, similar to the condition of the if statement is false.

Datamodel:

{
  "announce": false
}
Template:

Made it,Ma!{{?announce}}Top of the world!{{/announce}}
Made it,Ma!
{{?announce}}
Top of the world!🎋
{{/announce}}
Output:

Made it,Ma!
Made it,Ma!

Non-False Values and Not a collection

If the value of the section is not null, false, and is not a collection, all document elements in the section will be rendered once, similar to the condition of the if statement is true.

Datamodel:

{
  "person": { "name": "Sayi" }
}
Template:

{{?person}}
  Hi {{name}}!
{{/person}}
Output:

  Hi Sayi!

Non-Empty collection

If the value of the section is a non-empty collection, the document elements in the section will be looped once or N times, depending on the size of the collection, similar to the foreach syntax.

Datamodel:

{
  "songs": [
    { "name": "Memories" },
    { "name": "Sugar" },
    { "name": "Last Dance" }
  ]
}
Template:

{{?songs}}
{{name}}
{{/songs}}
Output:

Memories
Sugar
Last Dance
In the loop, a special tag {{=#this}} can be used to directly refer to the object of the current iteration.

Datamodel:

{
  "produces": [
    "application/json",
    "application/xml"
  ]
}
Template:

{{?produces}}
{{=#this}}
{{/produces}}
Output:

application/json
application/xml

The Java code developed to create the iris4word library

The iris4word was created using Java. The InterSystems IRIS supports use Java libraries with External Java Gateway feature:

ClassMethod GenerateWordFileFromJSON(jsonContent As %String, wordTemplateFileName As %String, wordFileName As %String) As %Status
{
    Set tSC = $$$OK

    Try {
        
        set javaGate = $system.external.getJavaGateway()  
        do javaGate.addToPath($SYSTEM.Util.BinaryDirectory()_"iris4word-1.0.0-jar-with-dependencies.jar")
        set wordUtil = javaGate.new("iris4word.WordUtil")
...
}

The instruction $system.external.getJavaGateway returned a Java engine and the addToPath allow us to use the file iris4word-1.0.0.0-jar-with-dependencies.jar. This library has the iris4word implementation:

package iris4word;

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.IOException;
import java.util.Map;

public class WordUtil {

    public void createFromFile(String jsonFileName, String wordTemplateFileName, String wordFileName) {
        
    	java.util.logging.Logger julLogger2 = java.util.logging.Logger.getLogger("com.deepoove.poi.render.processor.LogProcessor");
    	julLogger2.setLevel(java.util.logging.Level.OFF);
    	
    	java.util.logging.Logger julLogger = java.util.logging.Logger.getLogger("org.slf4j.Logger");
        julLogger.setLevel(java.util.logging.Level.OFF);
        
    	ObjectMapper objectMapper = new ObjectMapper(); 
    	XWPFTemplate template = null;
    	
        try {
            File jsonFile = new File(jsonFileName);
            
            @SuppressWarnings("unchecked")
			Map<String, Object> data = objectMapper.readValue(jsonFile, Map.class);

            Configure config = Configure.builder().build();

            template = XWPFTemplate.compile(wordTemplateFileName, config).render(data);

            template.writeToFile(wordFileName);
            

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        	if(template != null) {        		
        		try {
					template.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
        	}
		}
    }
	
}

The iris4word used the open source library poi-tl (package com.deepoove.poi) to render word templates with dynamic data. The iris4word transform JSON data to the poi-tl format, set the data to poi-tl, execute the rendering process and get the word document. The document is saved to the disk to be used into ObjectScript code:

ClassMethod GenerateWordFile(jsonFileName As %String, wordTemplateFileName As %String, wordFileName As %String) As %Status
{
    Set tSC = $$$OK

    Try {
        
        set javaGate = $system.external.getJavaGateway()  
        do javaGate.addToPath($SYSTEM.Util.BinaryDirectory()_"iris4word-1.0.0-jar-with-dependencies.jar")
        set wordUtil = javaGate.new("iris4word.WordUtil") 
        
        do wordUtil.createFromFile(jsonFileName, wordTemplateFileName, wordFileName)
        
    }
    Catch ex {
        Set tSC=ex.AsStatus()
    }

    return tSC
}

This project demonstrates how not only Python, but also Java, can significantly extend IRIS's functionality. Enjoy!

2 Comments
Discussão (2)1
Entre ou crie uma conta para continuar
Discussão (0)1
Entre ou crie uma conta para continuar
Artigo
· Jul. 25 10min de leitura

Évolutivité massive avec la plateforme de données InterSystems IRIS

Confrontés aux volumes considérables et sans cesse croissants de données générées dans le monde aujourd'hui, les architectes logiciels doivent accorder une attention particulière à l'évolutivité de leurs solutions. Ils doivent également concevoir des systèmes capables, si nécessaire, de gérer plusieurs milliers d'utilisateurs simultanés. Ce n'est pas facile, mais il est absolument indispensable de concevoir des systèmes hautement évolutifs.

On compare une charge de travail moyenne de 1 000 requêtes de 1 kilo-octet par seconde à une autre impliquant 10 requêtes de 1 téraoctet par heure

Les architectes logiciels disposent de plusieurs options pour concevoir des systèmes évolutifs. Ils peuvent procéder à une évolutivité verticale en utilisant des machines plus puissantes dotées de dizaines de processeurs. Ils peuvent utiliser des techniques de distribution (réplication) des données pour procéder à une évolutivité horizontale afin d'accueillir un nombre croissant d'utilisateurs. Et ils peuvent faire évoluer le volume de données horizontalement grâce à une stratégie de partitionnement des données. Dans la pratique, les architectes logiciels emploient plusieurs de ces techniques, en trouvant un compromis entre les coûts liés au matériel, la complexité du code et la facilité de déploiement afin de répondre à leurs besoins spécifiques.

Cet article explique comment la plateforme de données InterSystems IRIS Data Platform prend en charge l'évolutivité verticale et horizontale des volumes de données et d'utilisateurs. Il présente plusieurs options de distribution et de partitionnement des données et/ou du volume d'utilisateurs, en donnant des exemples de scénarios où chaque option serait particulièrement utile. Enfin, cet article explique comment InterSystems IRIS contribue à simplifier la configuration et le provisionnement des systèmes distribués.

Discussão (0)1
Entre ou crie uma conta para continuar
Anúncio
· Jul. 25

[Demo Video] Healthcare AI Agent Platform

#InterSystems Demo Games entry


⏯️ Healthcare AI Agent Platform

An AI Agent Platform specifically built for the healthcare industry that requires no technical background to utilize. By simply defining a goal or initiative, a swarm of AI agents will conduct operations to achieve the stated end goal and measure their own efficacy along the way to continuously improve. Healthcare organizations today are facing a myriad of challenges that impact financial and clinical performance. These problems are well known, and there is a general consensus on how many of them can be alleviated with AI. However, healthcare organizations face unique challenges in implementing AI:

  • HIPAA/Regulatory compliance - Data quality & accessibility - Embedding AI into current clinical workflows, i.e. integrating AI in such a way that it does not require clinicians to re-orient their processes. It should complement existing workflows, not disrupt them.
  • Implementation cost/high technical barrier of entry – staff needed to build and maintain AI processes can become expensive
  • Ambiguous ROI calculation – careful considerations must be made to properly measure and understand the efficacy of AI integrations. InterSystems is uniquely positioned to address these challenges, enabling healthcare organizations to implement AI with minimal burden.

Presenters:
🗣 @Daniel Cole, Sales Engineer, InterSystems
🗣 @Jeff Morgan, Sales Engineer, InterSystems
🗣 @Raef Youssef, Sales Engineer, InterSystems
🗣 @Jose Ruperez, Senior Sales Engineer, InterSystems
🗣 @Harry Tong, Principal Solutions Architect, InterSystems
🗣 @Nicholai Mitchko, Sales Engineering Manager, InterSystems

👉 Like this demo? Support the team by voting for it in the Demo Games!

Discussão (0)1
Entre ou crie uma conta para continuar