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

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.

相关推荐
热点推荐
缅北女魔头魏榕,帅哥真实自述:把我关进狗笼,我口腔感染了3次

缅北女魔头魏榕,帅哥真实自述:把我关进狗笼,我口腔感染了3次

马尔科故事会
2024-06-15 11:51:34
有猫腻,银行取钱要派出所同意,银行却被爆出内部员工私转230万

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

三月柳
2024-06-15 10:28:42
1场3-1后,积分榜又变化!意大利坐2望1,中国女排第6,将战NO.1

1场3-1后,积分榜又变化!意大利坐2望1,中国女排第6,将战NO.1

刘姚尧的文字城堡
2024-06-15 16:26:34
突然宣布!王力宏请辞!

突然宣布!王力宏请辞!

博览新闻
2024-06-15 10:46:08
成都计划到2027年累计淘汰老旧汽车30万辆

成都计划到2027年累计淘汰老旧汽车30万辆

北青网-北京青年报
2024-06-13 17:29:04
银行副行长误将女员工表白视频群发,两人相差20岁,官方发声力挺

银行副行长误将女员工表白视频群发,两人相差20岁,官方发声力挺

求实者
2024-06-14 22:18:32
御姐风!太高级!要不起的感觉

御姐风!太高级!要不起的感觉

梧州生活宝
2024-05-22 23:14:03
国足接连躺赢?亚洲区18强分组揭秘,世界杯决赛圈国足稳了

国足接连躺赢?亚洲区18强分组揭秘,世界杯决赛圈国足稳了

林子说事
2024-06-15 10:14:38
凯特站C位,查尔斯力挺儿媳,卡米拉被边缘化表情严肃,威廉放松

凯特站C位,查尔斯力挺儿媳,卡米拉被边缘化表情严肃,威廉放松

亦纯杂谈
2024-06-15 23:51:45
原来新冠疫情已被写进历史书了!128个字讲述3年,家长们五味杂陈

原来新冠疫情已被写进历史书了!128个字讲述3年,家长们五味杂陈

户外阿毽
2024-06-14 22:50:19
曝45岁伏明霞离婚,净身出户原因揭晓,71岁百亿丈夫只说6个字

曝45岁伏明霞离婚,净身出户原因揭晓,71岁百亿丈夫只说6个字

深度知局
2024-05-20 19:25:53
张学良推测:西安事变的实际策划者,是共产党员王炳南

张学良推测:西安事变的实际策划者,是共产党员王炳南

奇人奇史
2024-06-15 01:55:03
董路:武磊射门进球转化率20%,高于萨拉赫&仅差哈兰德两个百分点

董路:武磊射门进球转化率20%,高于萨拉赫&仅差哈兰德两个百分点

直播吧
2024-06-15 21:21:04
如果毛岸英不牺牲,毛主席会不会让他接班?历史早就给出了答案

如果毛岸英不牺牲,毛主席会不会让他接班?历史早就给出了答案

文史旺旺旺
2024-06-11 19:42:16
突发!云南省纪委再发力,两人同日被查落马,坐标文山州

突发!云南省纪委再发力,两人同日被查落马,坐标文山州

小尚爱科普
2024-06-16 00:11:12
姜萍父亲发声,家庭困难住着烂房子,姐妹都是学霸,刘奔爆笑回应

姜萍父亲发声,家庭困难住着烂房子,姐妹都是学霸,刘奔爆笑回应

兰子记
2024-06-15 21:53:08
富士康“赌输”了!损失3千亿美金,郭台铭没想到,会来的这么快

富士康“赌输”了!损失3千亿美金,郭台铭没想到,会来的这么快

户外阿崭
2024-06-15 18:13:34
众生相!东欧造惨案碰头拥抱互相激励 绿军刷爆耻辱纪录集体黑脸

众生相!东欧造惨案碰头拥抱互相激励 绿军刷爆耻辱纪录集体黑脸

厝边人侃体育
2024-06-15 10:53:35
1981年,他被连队关禁闭借故爬上大树解闷,一亮光改变了他的人生

1981年,他被连队关禁闭借故爬上大树解闷,一亮光改变了他的人生

百年历史老号
2024-06-12 07:38:26
美媒:美西南航空一架波音737 Max 8型客机在高空发生“荷兰滚”现象

美媒:美西南航空一架波音737 Max 8型客机在高空发生“荷兰滚”现象

环球网资讯
2024-06-15 16:10:11
2024-06-16 03:04:49
墨谈科技
墨谈科技
业务数码玩家.无聊的博主
2987文章数 567关注度
往期回顾 全部

科技要闻

TikTok开始找退路了?

头条要闻

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

头条要闻

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

体育要闻

莱夫利,让困难为我让路

娱乐要闻

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

财经要闻

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

汽车要闻

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

态度原创

艺术
数码
教育
房产
本地

艺术要闻

穿越时空的艺术:《马可·波罗》AI沉浸影片探索人类文明

数码要闻

低至 5747 元,爱普生 CH-TW6280T 真 4K 投影仪京东大促

教育要闻

厉害!长沙15岁初三少年闯进2024年阿里巴巴全球数学竞赛决赛

房产要闻

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

本地新闻

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

无障碍浏览 进入关怀版