javascript - 使用 Node.js 使用数据库值生成动态 word 文档

标签 javascript node.js sqlite express docx

我正在尝试使用 npm docx 动态填充 WORD 文档。我正在尝试从 SQLite 数据库读取数据,但由于异步 Node js 属性,值未进入变量并显示 undefined。如果我使函数同步,npm docx 会抛出错误并且不会填充文档。

包.json

{
  "name": "demoName",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "docx": "^5.1.1",
    "express": "^4.17.1",
    "md5": "^2.2.1",
    "sqlite3": "^4.2.0"
  }
}

索引.js

const docx = require('docx');
var express = require('express');
var app = express();
var db = require("./database.js")

var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

const { AlignmentType, Document, Footer, Header, HeadingLevel, Packer, Paragraph, TextRun, UnderlineType, Table, TableCell, TableRow } = docx;

app.get("/doc", async(req, res) => {
    var sql = "select * from DocDetails"
    var params = []
    //let DocDetailsData;
    //let DocDetailsData = [{docId: "Some Doc Id"}];
    const DocDetailsData = db.all(sql, params, (err, rows) => {

        if (err) {
          res.status(400).json({"error":err.message});
          return;
        }
        console.log(rows[0]);
        return rows[0];

    });
    console.log(DocDetailsData.docId);

    const doc = new Document();
    doc.addSection({
        children: [
            new Paragraph({
                children: [
                    new TextRun({
                        text: "DEMO TEST DOCUMENT"
                    }),
                    new TextRun({
                        text: DocDetailsData.docId,
                    }),
                ]
            }),
        ],
    });

    const b64string = await Packer.toBase64String(doc);
    res.setHeader('Content-Disposition', 'attachment; filename=My Document.docx');
    res.send(Buffer.from(b64string, 'base64'));
});

madeDoc = function(){


}

app.use(function(req, res){
    res.status(404);
});

var server = app.listen(4041, function () {
   var host = 'localhost'
   var port = server.address().port

   console.log("Example app listening at http://%s:%s", host, port)
})

数据库.js

var sqlite3 = require('sqlite3').verbose()
var md5 = require('md5')

const DBSOURCE = "db.sqlite"

let db = new sqlite3.Database(DBSOURCE, (err) => {
    if (err) {
      // Cannot open database
      console.error(err.message)
      throw err
    }else{
        console.log('Connected to the SQLite database.')
        db.run(`CREATE TABLE DocDetails (
            id INTEGER PRIMARY KEY,
            docId text NOT NULL,
            version float NULL,
            editedBy text NULL,
            editedDate text NULL,
            effectiveDate text NULL)`,
          (err) => {
              if (err) {
                  // Table already created
                  console.log('Table not created');
              }else{
                  console.log('Table created');
                  var insert = 'INSERT INTO DocDetails (docId, version, editedBy, editedDate, effectiveDate) VALUES (?,?,?,?,?)'
                  db.run(insert, ["NESS-RD-TEMP-EDCHB",2.1, "manab", "18-Jul-2017", "18-Jul-2020"])
              }
          })
    }
});


module.exports = db

如果您转到 localhost:4041/doc,应该会下载一个 word 文档,但它只显示一行,而不是数据库中的数据。我需要在文档中填充数据库值。 谢谢。

最佳答案

为了使该示例正常运行,您需要了解如何使用异步执行和回调。您不能像在同步代码中那样从回调中返回任何内容并在 DocDetailsData 变量中获取它,因为当您调用 db.all 方法时,代码会继续执行,而无需等待您传递给它的回调起作用.相反,您需要将生成 doc 文件的代码放在回调中并在其中执行。我希望至少我可以向您解释它是如何工作的。这就是您的代码将如何正常工作:

索引.js

const docx = require('docx');
var express = require('express');
var app = express();
var db = require("./database.js")

var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

const { AlignmentType, Document, Footer, Header, HeadingLevel, Packer, Paragraph, TextRun, UnderlineType, Table, TableCell, TableRow } = docx;

app.get("/doc", async (req, res) => {
    var sql = "select * from DocDetails"
    var params = []

    db.all(sql, params, async (err, rows) => {
        if (err) {
          res.status(400).json({"error":err.message});
          return;
        }

        const DocDetailsData = rows[0];

        const doc = new Document();
        doc.addSection({
            children: [
                new Paragraph({
                    children: [
                        new TextRun({
                            text: "DEMO TEST DOCUMENT"
                        }),
                        new TextRun({
                            text: DocDetailsData.docId,
                        }),
                    ]
                }),
            ],
        });

        const b64string = await Packer.toBase64String(doc);
        res.setHeader('Content-Disposition', 'attachment; filename=My Document.docx');
        res.send(Buffer.from(b64string, 'base64'));
    });
});


app.use(function(req, res){
    res.status(404);
});

var server = app.listen(4041, function () {
   var host = 'localhost'
   var port = server.address().port

   console.log("Example app listening at http://%s:%s", host, port)
});

database.js 不需要改动

关于javascript - 使用 Node.js 使用数据库值生成动态 word 文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62366327/

相关文章:

具有最高编号的 Javascript 变量

javascript - 如何解决模板包错误?

Node.js 同步调用收集结果

ios - SQLite 数据库崩溃

javascript - 为 cookie key 取一个随机指数值

javascript - 图像/视频以纵向纵横比覆盖整个屏幕

javascript - ~~ 在 javascript 中是什么意思?

node.js - express app.use middle layer 进行身份验证

javascript - express.js 中的常用函数放在哪里?

sqlite - 将NULL转换为默认值