千家信息网

javascript怎么实现使用动态图像生成文档

发表于:2024-11-26 作者:千家信息网编辑
千家信息网最后更新 2024年11月26日,这篇文章主要为大家展示了"javascript怎么实现使用动态图像生成文档",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"javascript怎么实现使用动
千家信息网最后更新 2024年11月26日javascript怎么实现使用动态图像生成文档

这篇文章主要为大家展示了"javascript怎么实现使用动态图像生成文档",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"javascript怎么实现使用动态图像生成文档"这篇文章吧。

Adobe Document Generation最吸引人的方面之一是它非常灵活。API 可以真正增强最终结果的一个方面是能够在模板中包含图像。在典型的用例中,您将提供在与 API 一起使用的数据中定义的静态图像。在这篇博文中,我将展示一个更高级的例子--动态生成图像,在我们的例子中是动态生成图表。

基础知识

在我们进入更高级的演示之前,让我们快速介绍一下基础知识。(我的同事非常深入地研究了文档生成和图像,您也应该检查一下。)正如我们的文档所述,在 Word 模板中使用动态图像需要几个步骤。

首先,您将图像添加到文档中。您选择什么图像并不重要,它只是一个占位符,但您需要根据需要将其放置在文档中,并确保已按预期调整其大小。完成后,右键单击图像并选择"编辑替换文字"选项。在该替代文本中,您提供 JSON:

JSON:

{  "location-path" : "logo" ,  "image-props":{     "alt-text": "This is an alt-text for the image placeholder"  }}

location-path属性必须指向包含图像数据的数据中使用的键值。例如,给定上述location-path值,我与 API 一起使用的数据可能如下所示:

JSON:

{  "name" : "Some Random Name" ,
"age" : 48 , "logo" : ""
}

如示例所示,图像数据必须是图像的 Base64 编码版本。如果你以前从未见过,它看起来有点像这样:

数据:图像/png;base64,一个非常长的字符列表

您还可以使用 Word Add On 为您插入图像。如果您添加的示例数据包含 Base64 值,则您可以在"高级"选项卡的"图像"部分中选择它。

所以此时,您已经能够动态更改最终结果 PDF 或 Word 文档中的图像。为此,您需要换出值。想象一下,对于文档中的图像,您有两个选项,一张猫的图片或一张狗的图片。在 Word 模板中,您嵌入了一个占位符图像并将其链接到一个值pet. 在将您的模板和数据发送到 Document Generation API 之前,您将使用正确的值:

// data is the object you will pass to the API, it's got stuff alreadyif(thisPersonIsVeryCool) {    data.pet = catBase64ImageData;} else {    data.pet = dogBase64ImageData;}// now call our API and pass the template and data

如您所见,根据某些特定的布尔值,数据将具有猫或狗图片的编码版本。(显然一个比另一个好,当然我说的是猫。)

虽然这符合动态,但我们可以更进一步。

使用动态图像

对于我们的场景,我们将创建一个文档,描述过去六个月收容所中猫的数量。这些数据是从内部报告系统返回的,可以这样表示:

JSON:

{ {     "numberOfCats": [        {"date":"11/2020", "amount":210},        {"date":"12/2020", "amount":354},        {"date":"1/2021", "amount":321},        {"date":"2/2021", "amount":337},        {"date":"3/2021", "amount":298},        {"date":"4/2021", "amount":274}    ]}

数据由从最旧到最新排序的值数组组成。数组中的每个项目都有一个日期戳和一个数字金额。让我们从一个包含数据表的模板开始。


就其本身而言,它既漂亮又简单,并且输出干净。这是生成 PDF 时的样子:


它"有效",但图表可以使它更容易阅读。您可以更清楚地看到一段时间内的趋势,并根据提供的数据做出更好的判断。但是我们如何在 Word 模板中获取动态图表呢?

首先,我们需要找到一个可以同时创建图表的服务,这是至关重要的部分,让我们可以访问图表的原始图像数据。你看,有大约一千种图表服务,专门为网络开发人员服务。然而,许多这些图表库将在浏览器环境中以及在查看特定网页的 JavaScript 时呈现它们的库。我们需要的是一种创建实际图像的服务,该图像可以通过我们的服务器端代码请求并转换为 Base64。

对于我们的演示,我们将使用QuickChart。QuickChart 是围绕开源Chart.js包的"服务包装器" 。它基本上采用了 Chart.js 的功能,并允许您通过制作 URL 来获取图表的静态图像。例如,考虑这个 URL:

https://quickchart.io/chart?c={type:'bar',data:{labels:['Q1','Q2','Q3','Q4'], datasets:[{label:'Users ',data:[50,60,70,180]},{label:'Revenue',data:[100,200,300,400]}]}}

您可以看到定义图表各个方面的 URL 参数,包括类型 ( bar)、标签和实际数据。你可以在这里看到结果:


虽然 URL 有点复杂(甚至可能更复杂),但它为我们的问题提供了解决方案。鉴于我们拥有来自内部 API 的数据,我们所要做的就是在适用于 QuickChart 的 URL 中"重写"它。

我先建了那个。它接受我的有序数据并使用它在 QuickChart 上创建一个 URL,该 URL 使用折线图格式并指定特定的高度和宽度。这是那个函数:

function generateQuickChartURL(arr) {    let labels = arr.map(d => d.date);    let data = arr.map(d => d.amount);       let url = `https://quickchart.io/chart?c={type:'line',data:{labels:${JSON.stringify(labels)},datasets:[{label:'Cats',data:${JSON.stringify(data)}}]}}&width=500&height=300`;    return url;    }

如果我想添加更多图表功能,比如自定义颜色,我会在这里修改。完成后,我在 Word 文档中添加了一个占位符图像并指定了大小。Ben 在他的精彩文章Adobe 文档生成 API:处理图像中将此作为技巧 6 进行了介绍。

我要添加到此建议中的一件事是将 Word 切换为对图像使用像素高度和宽度而不是英寸。在 Word 设置中的高级下,转到显示并启用"显示 HTML 功能的像素":


启用此功能后,我们可以为图像设置特定的高度和宽度(500 x 300)并将其居中放置在表格下方。


图片的替代文字如下所示:

{"location-path": "image"}

提醒一下,这意味着当我们将数据传递给文档生成 API 时,它会期望image密钥包含我们图像的 Base64 数据。我们怎么做?还有一个功能!

JSON:

async function urlToBase64(url) {    let resp = await fetch(url);    let header = resp.headers.get('content-type');    let body = await resp.arrayBuffer();    data = _'data:' + resp.headers.get('content-type') + ';base64,' + Buffer.from(body).toString('base64');    return data;}

urlToBase64函数完全符合它的要求 - 访问远程 URL,获取数据,然后对其进行转换。现在我们拥有了我们需要的所有部分,让我们看一个完整的例子:

const PDFToolsSdk = require('@adobe/documentservices-pdftools-node-sdk');const fs = require('fs');const fetch = require('node-fetch');(async () => {    let input = './catreport.docx';    let data = JSON.parse(fs.readFileSync('./cats.json'));    let output = './catreport.pdf';    if(fs.existsSync(output)) fs.unlinkSync(output);    let url = generateQuickChartURL(data.numberOfCats);    // get my image     data.image = await urlToBase64(url);    await generateFromTemplate(input, data, output, './pdftools-api-credentials.json');})();/*I'm specifically designed to return a url for a line item chart based on my cat array - must include 'date' and 'amount'*/function generateQuickChartURL(arr) {let labels = arr.map(d => d.date);    let data = arr.map(d => d.amount);    let url = `https://quickchart.io/chart?c={type:'line',data:{labels:${JSON.stringify(labels)},datasets:[{label:'Cats',data:${JSON.stringify(data)}}]}}&width=500&height=300`;    return url;    }async function urlToBase64(url) {    let resp = await fetch(url);    let header = resp.headers.get('content-type');    let body = await resp.arrayBuffer();    data = _'data:' + resp.headers.get('content-type') + ';base64,' + Buffer.from(body).toString('base64');    return data;}async function generateFromTemplate(template, data, dest, creds) {    return new Promise((resolve, reject) => {        // Initial setup, create credentials instance.        const credentials =  PDFToolsSdk.Credentials        .serviceAccountCredentialsBuilder()        .fromFile(creds)        .build();        // Create an ExecutionContext using credentials.        const executionContext = PDFToolsSdk.ExecutionContext.create(credentials);        const documentMerge = PDFToolsSdk.DocumentMerge,        documentMergeOptions = documentMerge.options;        //dest determines if Word or PDF        let format;        let destExt = dest.split('.').pop().toLowerCase();        if(destExt === 'docx') format = documentMergeOptions.OutputFormat.DOCX;        else if(destExt === 'pdf') format = documentMergeOptions.OutputFormat.PDF;        else throw('Invalid destination extension')        // Create a new DocumentMerge options instance.        options = new documentMergeOptions.DocumentMergeOptions(data, format);        // Create a new operation instance using the options instance.        const documentMergeOperation = documentMerge.Operation.createNew(options);        // Set operation input document template from a source file.      const input = PDFToolsSdk.FileRef.createFromLocalFile(template);        documentMergeOperation.setInput(input);        // Execute the operation and Save the result to the specified location.        documentMergeOperation.execute(executionContext)        .then(result => result.saveAsFile(dest))        .then(() => resolve(true))        .catch(err => {            if(err instanceof PDFToolsSdk.Error.ServiceApiError                || err instanceof PDFToolsSdk.Error.ServiceUsageError) {                console.log('Exception encountered while executing operation', err);                reject(err);            } else {                console.log('Exception encountered while executing operation', err);                reject(err);            }        });    });}

从顶部开始,我首先为我的输入、数据和输出指定变量。在这种情况下,我的 cat 数据是一个硬编码的 JSON 文件,如上所示。然后我调用generateQuickChatURL我的数据并将结果分配给image值。最后,这将传递给generateFromTemplate使用我们的 SDK 创建 PDF的实用程序函数 ( )。

以上是"javascript怎么实现使用动态图像生成文档"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

0