网易首页 > 网易号 > 正文 申请入驻

Javascript基于模板生成PDF 文档

0
分享至

在您的 js 应用程序中使用 eDocGen 从 JSON/XML/Database 创建 PDF 文档的指南。

文档生成是开发人员生活中非常普遍的需求。无论是电子商务网站、管理应用程序还是其他任何东西。它可以是发票生成、保险文件准备、医生处方、人力资源报价生成、工资单生成,你可以想到大量的用例。总是需要生成文档。

从开发人员的角度来看,有几种常见的方法可以完成这项工作。

  1. 创建 HTML 元素并打印它们以生成文档
  2. 使用一些库来生成文档
  3. 让服务器处理基于静态模板的文档生成

这些方法对我没有帮助。客户希望自己定制他们的文件。我一直在寻找一种方法,发现eDocGen是一种单点解决方案。

与其他服务不同,eDocGen 提供了可以集成到我们应用程序中的 RestAPI。

在本文中,我们将讨论如何将 eDocGen 集成到我们的 js 应用程序中,以从各种数据格式(如 JSON/XML/Database 模式)生成文档。请免费试用以开始编码。

让我们潜入并编写代码。

项目设置

出于演示目的,我创建了一个在 nodejs 上运行的示例 js 应用程序。

请按照以下步骤为我们设置编码游乐场。

步骤1:

用于npm init创建 package.json

第2步:

添加axios, form-data, request,xhr2开发此应用程序所需的依赖项npm install axios form-data request xhr2

第 3 步:

我们需要一个索引文件作为我们应用程序的起点。在根目录中创建一个 index.js 文件并修改 package.json 如下所示。

JSON

scripts": {
"start": "node index.js"
}

现在我们有一个基本的应用程序可以开始。这些步骤结束后,package.json 应该如下所示。

JSON

{
"name": "nodejs-multiple-upload-files",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"axios": "^0.27.2",
"form-data": "^4.0.0",
"request": "^2.88.2",
"xhr2": "^0.2.1"
}
}

登录

虽然这篇文章是关于文档生成的,但我们需要登录才能获取我们的访问令牌。这是一个典型的JWT令牌,将用于授权文档生成 API。

JavaScript

var XMLHttpRequest = require("xhr2");
var xhr = new XMLHttpRequest();
module.exports.getToken = function (callback) {
var data = JSON.stringify({
username: "

",
password: "

",
});
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
token = JSON.parse(this.responseText).token;
console.log("User Token", token);
callback(token);
}
});
xhr.open("POST", "https://app.edocgen.com/login");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.send(data);
};

我们可以将令牌在应用程序中缓存一个小于过期时间的时间段,并使用它来生成文档或上传模板。到期时间过后,我们可以刷新令牌。缓存可以是 Redis 或内存缓存。这取决于您的应用程序设计。

模板设计

如上所述,eDocGen 允许用户自定义和上传模板。但是如何动态映射数据呢?有一些将数据映射到文档的规则。我们将看到如何使用规则创建模板。

看看这个文件。

eDocGen{}对动态字段使用由 括起来的标签。我们可以动态添加文字、logo、表格、条件语句、数学计算等。

例如,在上图中,

字符串字段:{Invoice_Number}并{Invoice_Date}配置为替换为模板中的文本。模板中 {} 内的任何内容都将与输入数据匹配并替换。

动态表:当表中存在需要循环和替换的数据数组时,动态表将是一个不错的选择。表中的行以 开头{#tablename}和结尾{/tablename}。在上面的示例中,发票表中的一行在第一列以 {#IT} 开头,在最后一列以 {/IT} 结尾。行中的列可以有字符串字段。在我们的示例中,{Item_description}并且{Amount}

图片:eDocGen 提供动态添加图片到模板的功能。请按照以下步骤操作。

  • 将图像上传到应以 image_id 响应的 eDogGen。
  • {%image_id}是用于填充图像的标签。图像image_id将从 eDocGen 存储中获取并替换为{%image_id}. 预计image_id将出现在输入数据中。

基于条件的动态字段(If-Else):可以使用条件标签有条件地显示内容。例如,当语言为英语时,文档中会显示{#language == "english"} 英语内容。同样,单个文档模板可以支持多种语言。

数学计算:eDocGen 支持基于模板中定义的公式的数学计算。可以使用以下公式计算发票中项目金额的总和。

JSON

{
IT // array of items
| summation:'Amount' // value that needs to be used for calculation
| format_number: ",” // format of the value
}

请前往JSON-to-pdf了解更多详情。

模板上传

准备好模板后,就可以将其上传以供使用。有两种方法。

  1. eDocGen 的交互式 UI - 与 Dropbox、驱动器、Evernote 集成
  2. eDocGen 的 RestAPI - 可以集成到客户端代码中以上传模板。

对于演示,我使用 UI 来上传模板。成功上传后,我们会得到一个 ID 作为响应。这是将用于生成文档的 ID。

如果您希望使用 API,请在此处留下 Upload API 结构供您参考。

JSON

"/api/v1/document": {
"post": {
"tags": [
"Document"
],
"description": "Upload template to eDocGen",
"produces": [
"application/json"
],
"consumes": [
"multipart/form-data"
],
"parameters": [
{
"name": "documentFile",
"description": "file to upload",
"required": true,
"type": "file",
"in": "formData"
},
{
"name": "x-access-token",
"in": "header",
"description": "JWT auth token from login",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "Successfully uploaded document file"
},
"other": {
"description": "Operation failed"
}
}
}
}

JSON 到文档生成

现在我们准备好了模板。让我们生成文档。

文档生成有两个阶段。

  1. 请求生成文档
  2. 下载文件

第 1 步:请求生成文档

我们要求生成包含所需详细信息的文档,并得到确认。该过程异步发生在屏幕后面。

文档生成所需的参数

应用程序接口:POST-/api/v1/document/generate/bulk

请求正文

表格数据

文档 ID

模板的id

格式

pdf/docx(模板应支持格式)

输出文件名

输出文件的文件名。

输入文件

该文件包含标记值。支持 json、xlsx 和 xml。

标题

内容类型

多部分/表单数据

x-访问令牌

来自登录的 JWT 身份验证令牌

输入数据

inputFile 中的数据应该是模板定义的结构。例如,对于上面的模板映射将如下所示。

  • Invoice_Number在 JSON 中应该与{Invoice_Number}模板中的匹配。
  • 对于表数据,它应该是一个对象数组,带有Item_Description和Amount.
  • 金额应该是一个用于求和计算的数字。

第 2 步:下载文件

可以使用从上述步骤中获得的输出 ID 和输出文件的名称下载生成的文档。

我们将在这里使用两个 API。

  1. 了解文件存在的 API:/api/v1/output/name/${fileName}
  2. 下载文件的API:/api/v1/output/download/${outputId}

由于文档生成是异步发生的,要知道文档是否生成,我们将使用/api/v1/output/nameapi。

来自 API 的成功响应/api/v1/output/name将下载文件。

我将这两个步骤组合在一个 js 文件中,如下所示。

爪哇

let login = require("../edocgen_login");
const fs = require("fs");
const uuid = require("uuid");
const FormData = require("form-data");
let axios = require("axios");
let fileName = uuid.v4();
const headers = {
"Content-Type": "multipart/form-data",
"x-access-token": "null",
};
const hostName = "https://app.edocgen.com/api/v1/document/generate/bulk";
const outputFormat = "

";// pdf / docx
const documentId = "

"; // id of the template we want to use
module.exports.generateFiles = function () {
let authToken = login.getToken(function handleUsersList(token) {
headers["x-access-token"] = token;
var formBody = new FormData();
formBody.append("documentId", documentId);
formBody.append("format", outputFormat);
formBody.append("outputFileName", fileName);
// json data for the template
formBody.append("inputFile", fs.createReadStream("./JSON_Data_Single.json")); // local path forjson file
let config = {
method: "post",
url: hostName,
headers: headers,
data: formBody,
};
console.log(`https://app.edocgen.com/api/v1/output/name/${fileName}.${outputFormat}`);
let config_output = {
method: "get",
url:`https://app.edocgen.com/api/v1/output/name/${fileName}.${outputFormat}`,
headers: headers,
};
const MAX_RETRY = 50;
let currentRetry = 0;
// max retry for 50 times
function errorHandler() {
if (currentRetry < MAX_RETRY) {
currentRetry++;
console.log("Document is not prepared yet! Retrying...");
sendWithRetry(processResponse);
} else {
console.log("No luck. Document is not generated. Retried multiple times.");
}
}
// sendWithRetry checks for file existence
// on success, it proceeds to download the file
// on failure, it retries
// todo: introduce spin lock
function sendWithRetry(callback) {
axios(config_output)
.then(function (response) {
if (response.data.output.length !== 1) {
throw new axios.Cancel("Document is not found. Throw error.");
} else {
callback(response);
}
})
.catch(errorHandler);
}
axios(config)
.then(function (response) {
sendWithRetry(processResponse);
})
.catch(function (error) {
console.log(error);
});
});
};
function processResponse(response) {
const outputId = response.data.output[0]._id;
console.log(
"Output Document is Generated. Id = ",
response.data.output[0]._id
);
let config_download = {
method: "get",
url: `https://app.edocgen.com/api/v1/output/download/${outputId}`,
headers: headers,
responseType: "arraybuffer",
};
axios(config_download)
.then(function (response) {
console.log("Output file is downloaded " + `${fileName}.${outputFormat}`);
fs.writeFileSync(`./${fileName}.${outputFormat}`, response.data);
})
.catch(function (error) {
console.log("Error while downloading");
console.log(error);
});
}

单个与多个文档

当数据为单个 JSON 时,将生成给定格式的单个文档。

当数据是对象数组时,将生成每个数组元素的文档并将其压缩到文件中。

XML 到文档生成

XML 数据的过程很简单。我们需要做的就是传递 XML 文件来代替 JSON 数据。

就像JSON to document,XML to Document 我们也需要documentId, outputFileName, format and inputFile。除输入文件外,与 JSON 相同的所有内容都将是 XML 文件。

示例 XML 数据如下所示

XML

SBU-2053501

31-07-2020

Net 15

ABC company

ABC-Contact1

New york, United State

support@edocgen.com

621cd2b783a6095d7b15a443

6,751

61b334ee7c00363e11da3439

Item Description

Amount

Product Fees: X

5,000

我为 XML 作为数据源所做的代码更改很简单,如下所示

JavaScript

var formBody = new FormData();
formBody.append("documentId", documentId);
formBody.append("format", outputFormat);
formBody.append("outputFileName", fileName);
formBody.append("inputFile", fs.createReadStream("./XML_Invoice.xml"));

数据库到文档生成

从数据库生成文档几乎与其他数据源相同。但在这种情况下,我们需要提供连接详细信息和 SQL 查询,而不是上传 inputFile。

SQL 查询的输出列应与文档模板中的标签匹配。

让我们看看如何在代码中进行配置。

JavaScript

const templateId = "

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
小学生吐槽学校食堂不卫生被处分后续,要求删除视频,评论区沦陷

小学生吐槽学校食堂不卫生被处分后续,要求删除视频,评论区沦陷

皖声微言
2024-06-14 08:41:36
宋慧乔9年前旧照被疯传,没了10级美妆,才知道啥叫纯天然美女

宋慧乔9年前旧照被疯传,没了10级美妆,才知道啥叫纯天然美女

木子爱娱乐大号
2024-06-15 17:26:09
姑娘你不能挡一下那里么?那东西让人看了很难为情,好尴尬!

姑娘你不能挡一下那里么?那东西让人看了很难为情,好尴尬!

水泥土的搞笑
2024-06-15 10:41:27
独行侠为什么能大胜凯尔特人?赛后苏群一席话,说得很实在

独行侠为什么能大胜凯尔特人?赛后苏群一席话,说得很实在

懂球哥评球
2024-06-15 12:27:24
同样是押运,为什么运钞车配的是霰弹枪,而押送高考卷配的是步枪

同样是押运,为什么运钞车配的是霰弹枪,而押送高考卷配的是步枪

小lu侃侃而谈
2024-06-14 22:22:24
啪啪扇脸打头,护工如此照顾老人?长期在国外的儿子回应:是亲戚,能理解……

啪啪扇脸打头,护工如此照顾老人?长期在国外的儿子回应:是亲戚,能理解……

新民周刊
2024-06-15 12:02:13
38年后,因流氓案“逃往”美国的龚雪,再看张颂文的话,令人深思

38年后,因流氓案“逃往”美国的龚雪,再看张颂文的话,令人深思

娱记掌门
2024-06-14 21:35:46
惊人消息!韦世豪或告别国家队,伊万、郑智的反应引发热议

惊人消息!韦世豪或告别国家队,伊万、郑智的反应引发热议

人生趣事悟语
2024-06-16 03:56:19
尴尬!颜宁现身武大演讲,学生叫院士遭打断并纠正,网友炸锅了

尴尬!颜宁现身武大演讲,学生叫院士遭打断并纠正,网友炸锅了

凯旋学长
2024-06-14 18:12:49
53年北京拆除大批古建筑,林徽因公开大骂副市长:将来你们要后悔

53年北京拆除大批古建筑,林徽因公开大骂副市长:将来你们要后悔

红色风云
2024-01-06 10:08:08
美俄核潜艇同时现身古巴,加拿大巡逻舰也到了,古巴副外长:美国未受邀请

美俄核潜艇同时现身古巴,加拿大巡逻舰也到了,古巴副外长:美国未受邀请

每日经济新闻
2024-06-15 13:48:05
取款超5万元需预约并说明用途!深圳:取钱转账办理时间超2小时

取款超5万元需预约并说明用途!深圳:取钱转账办理时间超2小时

大风文字
2024-06-15 08:47:47
世联赛最新排名出炉,中国女排第六,三球队争最后一个总决赛席位

世联赛最新排名出炉,中国女排第六,三球队争最后一个总决赛席位

湘楚风云
2024-06-16 02:19:01
好惨!黑龙江一轿车与货车相撞致:5死,死者身份曝出 评论区沦陷

好惨!黑龙江一轿车与货车相撞致:5死,死者身份曝出 评论区沦陷

小淇言说
2024-06-15 19:12:11
神奇换人!两小将临危受命直取关键两分,主导者不是蔡斌,而是她

神奇换人!两小将临危受命直取关键两分,主导者不是蔡斌,而是她

理工男评篮球
2024-06-16 00:29:00
人类为什么没有生殖隔离?

人类为什么没有生殖隔离?

读史
2024-06-14 07:00:30
有猫腻,银行取钱要派出所同意,银行却被爆出内部员工私转230万

有猫腻,银行取钱要派出所同意,银行却被爆出内部员工私转230万

三月柳
2024-06-15 10:28:42
发现妻子出轨第5天,我麻利做完财产分割,微笑祝福他俩白头偕老

发现妻子出轨第5天,我麻利做完财产分割,微笑祝福他俩白头偕老

星辰故事屋
2024-06-05 12:18:58
为什么“父亲节”变得如此低调呢?

为什么“父亲节”变得如此低调呢?

叒女紫121
2024-06-15 17:02:11
高潮只有2分钟,全网痛斥上当

高潮只有2分钟,全网痛斥上当

影探
2024-06-14 18:16:53
2024-06-16 05:20:49
墨谈科技
墨谈科技
业务数码玩家.无聊的博主
2987文章数 567关注度
往期回顾 全部

科技要闻

TikTok开始找退路了?

头条要闻

欧洲杯-亚马尔创纪录卡瓦哈尔首球 西班牙3-0克罗地亚

头条要闻

欧洲杯-亚马尔创纪录卡瓦哈尔首球 西班牙3-0克罗地亚

体育要闻

莱夫利,让困难为我让路

娱乐要闻

江宏杰秀儿女刺青,不怕刺激福原爱?

财经要闻

新情况!高层对人民币的态度180°转弯

汽车要闻

东风奕派eπ008售21.66万元 冰箱彩电都配齐

态度原创

本地
亲子
房产
健康
公开课

本地新闻

粽情一夏|海河龙舟赛,竟然成了外国人的大party!

亲子要闻

孩子总是便秘 家长要注意 这几点

房产要闻

万华对面!海口今年首宗超百亩宅地,重磅挂出!

晚餐不吃or吃七分饱,哪种更减肥?

公开课

近视只是视力差?小心并发症

无障碍浏览 进入关怀版