溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

javascript怎么實現(xiàn)使用動態(tài)圖像生成文檔

發(fā)布時間:2022-03-01 10:43:39 來源:億速云 閱讀:153 作者:小新 欄目:開發(fā)技術

這篇文章主要為大家展示了“javascript怎么實現(xiàn)使用動態(tài)圖像生成文檔”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“javascript怎么實現(xiàn)使用動態(tài)圖像生成文檔”這篇文章吧。

Adobe Document Generation最吸引人的方面之一是它非常靈活。API 可以真正增強最終結果的一個方面是能夠在模板中包含圖像。在典型的用例中,您將提供在與 API 一起使用的數(shù)據(jù)中定義的靜態(tài)圖像。在這篇博文中,我將展示一個更高級的例子——動態(tài)生成圖像,在我們的例子中是動態(tài)生成圖表。

基礎知識

在我們進入更高級的演示之前,讓我們快速介紹一下基礎知識。(我的同事非常深入地研究了文檔生成和圖像,您也應該檢查一下。)正如我們的文檔所述,在 Word 模板中使用動態(tài)圖像需要幾個步驟。

首先,您將圖像添加到文檔中。您選擇什么圖像并不重要,它只是一個占位符,但您需要根據(jù)需要將其放置在文檔中,并確保已按預期調整其大小。完成后,右鍵單擊圖像并選擇“編輯替換文字”選項。在該替代文本中,您提供 JSON:

JSON:

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

location-path屬性必須指向包含圖像數(shù)據(jù)的數(shù)據(jù)中使用的鍵值。例如,給定上述location-path值,我與 API 一起使用的數(shù)據(jù)可能如下所示:

JSON:

{  "name" : "Some Random Name" ,
   "age" : 48 ,    "logo" : "<base64 encoded image>"
}

如示例所示,圖像數(shù)據(jù)必須是圖像的 Base64 編碼版本。如果你以前從未見過,它看起來有點像這樣:

 數(shù)據(jù):圖像/png;base64,一個非常長的字符列表

您還可以使用 Word Add On 為您插入圖像。如果您添加的示例數(shù)據(jù)包含 Base64 值,則您可以在“高級”選項卡的“圖像”部分中選擇它。javascript怎么實現(xiàn)使用動態(tài)圖像生成文檔

所以此時,您已經(jīng)能夠動態(tài)更改最終結果 PDF 或 Word 文檔中的圖像。為此,您需要換出值。想象一下,對于文檔中的圖像,您有兩個選項,一張貓的圖片或一張狗的圖片。在 Word 模板中,您嵌入了一個占位符圖像并將其鏈接到一個值pet. 在將您的模板和數(shù)據(jù)發(fā)送到 Document Generation API 之前,您將使用正確的值:

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

如您所見,根據(jù)某些特定的布爾值,數(shù)據(jù)將具有貓或狗圖片的編碼版本。(顯然一個比另一個好,當然我說的是貓。)

雖然這符合動態(tài),但我們可以更進一步。

使用動態(tài)圖像

對于我們的場景,我們將創(chuàng)建一個文檔,描述過去六個月收容所中貓的數(shù)量。這些數(shù)據(jù)是從內部報告系統(tǒng)返回的,可以這樣表示:

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}
    ]
}

數(shù)據(jù)由從最舊到最新排序的值數(shù)組組成。數(shù)組中的每個項目都有一個日期戳和一個數(shù)字金額。讓我們從一個包含數(shù)據(jù)表的模板開始。

javascript怎么實現(xiàn)使用動態(tài)圖像生成文檔

就其本身而言,它既漂亮又簡單,并且輸出干凈。這是生成 PDF 時的樣子:

javascript怎么實現(xiàn)使用動態(tài)圖像生成文檔

它“有效”,但圖表可以使它更容易閱讀。您可以更清楚地看到一段時間內的趨勢,并根據(jù)提供的數(shù)據(jù)做出更好的判斷。但是我們如何在 Word 模板中獲取動態(tài)圖表呢?

首先,我們需要找到一個可以同時創(chuàng)建圖表的服務,這是至關重要的部分,讓我們可以訪問圖表的原始圖像數(shù)據(jù)。你看,有大約一千種圖表服務,專門為網(wǎng)絡開發(fā)人員服務。然而,許多這些圖表庫將在瀏覽器環(huán)境中以及在查看特定網(wǎng)頁的 JavaScript 時呈現(xiàn)它們的庫。我們需要的是一種創(chuàng)建實際圖像的服務,該圖像可以通過我們的服務器端代碼請求并轉換為 Base64。

對于我們的演示,我們將使用QuickChart。QuickChart 是圍繞開源Chart.js包的“服務包裝器” 。它基本上采用了 Chart.js 的功能,并允許您通過制作 URL 來獲取圖表的靜態(tài)圖像。例如,考慮這個 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 參數(shù),包括類型 ( bar)、標簽和實際數(shù)據(jù)。你可以在這里看到結果:

javascript怎么實現(xiàn)使用動態(tài)圖像生成文檔

雖然 URL 有點復雜(甚至可能更復雜),但它為我們的問題提供了解決方案。鑒于我們擁有來自內部 API 的數(shù)據(jù),我們所要做的就是在適用于 QuickChart 的 URL 中“重寫”它。

我先建了那個。它接受我的有序數(shù)據(jù)并使用它在 QuickChart 上創(chuàng)建一個 URL,該 URL 使用折線圖格式并指定特定的高度和寬度。這是那個函數(shù):

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 功能的像素”:

javascript怎么實現(xiàn)使用動態(tài)圖像生成文檔

啟用此功能后,我們可以為圖像設置特定的高度和寬度(500 x 300)并將其居中放置在表格下方。

javascript怎么實現(xiàn)使用動態(tài)圖像生成文檔

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

{"location-path": "image"}

提醒一下,這意味著當我們將數(shù)據(jù)傳遞給文檔生成 API 時,它會期望image密鑰包含我們圖像的 Base64 數(shù)據(jù)。我們怎么做?還有一個功能!

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函數(shù)完全符合它的要求 - 訪問遠程 URL,獲取數(shù)據(jù),然后對其進行轉換?,F(xiàn)在我們擁有了我們需要的所有部分,讓我們看一個完整的例子:

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);
            }
        });
    });
}

從頂部開始,我首先為我的輸入、數(shù)據(jù)和輸出指定變量。在這種情況下,我的 cat 數(shù)據(jù)是一個硬編碼的 JSON 文件,如上所示。然后我調用generateQuickChatURL我的數(shù)據(jù)并將結果分配給image值。最后,這將傳遞給generateFromTemplate使用我們的 SDK 創(chuàng)建 PDF的實用程序函數(shù) ( )。

以上是“javascript怎么實現(xiàn)使用動態(tài)圖像生成文檔”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI