使用Node.js使用数据库值生成动态Word文档

问题描述 投票:0回答:1

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

package.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"
  }
}

index.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)
})

database.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文档,但它仅显示一行,而不显示数据库中的数据。我需要在文档中填充数据库值。谢谢。

javascript node.js sqlite express docx
1个回答
0
投票

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

index.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不需要更改

© www.soinside.com 2019 - 2024. All rights reserved.