0

I have a simple csv file and want to render a html table from it using express and ejs.

csv:

,Unnamed: 0,sign_type,r1,g1,b1,r2,g2,b2,r3,g3,b3,r4,g4,b4,r5,g5,b5,r6,g6,b6,r7,g7,b7,r8,g8,b8,r9,g9,b9,r10,g10,b10,r11,g11,b11,r12,g12,b12,r13,g13,b13,r14,g14,b14,r15,g15,b15,r16,g16,b16
0,1,pedestrian,155,228,251,135,188,101,156,227,245,145,211,228,166,233,245,212,254,52,212,254,11,188,229,117,170,216,120,211,254,3,212,254,19,172,235,244,172,235,244,172,228,235,177,235,244,22,52,53
1,2,pedestrian,142,217,242,166,204,44,142,217,242,147,219,242,164,228,229,84,116,17,217,254,26,155,203,128,213,253,51,217,255,21,217,255,21,158,225,237,164,227,237,182,228,143,171,228,196,164,227,237
2,3,pedestrian,57,54,50,187,201,68,51,51,45,59,62,65,156,171,50,254,255,36,211,226,70,78,73,64,220,234,59,254,255,51,253,255,44,66,68,68,69,65,59,76,84,22,82,93,17,58,60,60
3,4,pedestrian,22,35,41,171,178,26,19,27,29,19,27,29,42,37,3,217,228,19,221,235,20,181,183,73,237,234,44,251,254,2,235,243,12,19,27,29,20,29,34,64,61,4,211,222,78,19,27,29
4,5,pedestrian,169,179,170,231,254,27,97,107,99,123,147,152,221,236,117,205,225,80,235,254,60,90,110,9,216,236,66,229,255,12,235,254,60,163,168,152,124,117,91,188,205,78,125,147,20,160,183,187

my .html file is as follows:

<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title>Table</title>
</head>

<body>
    <%= table %>
</body>

</html>

my app.js is:

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
let {PythonShell} = require('python-shell');

app.set('view engine', 'ejs');


app.get('/', function(req, res){
  var pyshell = new PythonShell('excel_to_html.py');
  pyshell.on('message', function (message) {

      res.render('list', {table: message}) // ###### console.log(message);
  });
  });

var port = 3000;
app.listen(port, function(){
  console.log('Server running on port ' + port)
});

and the python file which converts the .csv to html is:

import pandas as pd

def convert():
    csv_file = pd.read_csv('test.csv')
    html = csv_file.to_html()
    return html

if __name__ == '__main__':
    var = convert()
    print(var)

So summarizing:

1) I have a csv file and using a .py file and pandas to convert the csv into html.

2) I'm calling the python script inside the app.js file and getting the returned html.

3) I want to render that html table in my index.html using ejs.

If I replace the res.render('list', {table: message}) with the commented part console.log(message); I'm able to see the html table in the terminal log.

but when I try to render it using res.render('list', {table: message}) i get a not infinite looping error like this:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client 
    at ServerResponse.setHeader (_http_outgoing.js:485:11)
    at ServerResponse.header (E:\Documents\CODE\WebDev\todolist\v1\node_modules\express\lib\response.js:771:10)
    at ServerResponse.send (E:\Documents\CODE\WebDev\todolist\v1\node_modules\express\lib\response.js:170:12)
    at done (E:\Documents\CODE\WebDev\todolist\v1\node_modules\express\lib\response.js:1008:10)
    at tryHandleCache (E:\Documents\CODE\WebDev\todolist\v1\node_modules\ejs\lib\ejs.js:260:5)
    at View.exports.renderFile [as engine] (E:\Documents\CODE\WebDev\todolist\v1\node_modules\ejs\lib\ejs.js:459:10)
    at View.render (E:\Documents\CODE\WebDev\todolist\v1\node_modules\express\lib\view.js:135:8)
    at tryRender (E:\Documents\CODE\WebDev\todolist\v1\node_modules\express\lib\application.js:640:10)
    at Function.render (E:\Documents\CODE\WebDev\todolist\v1\node_modules\express\lib\application.js:592:3)
    at ServerResponse.render (E:\Documents\CODE\WebDev\todolist\v1\node_modules\express\lib\response.js:1012:7)

And I get only this in the browser:

<table border="1" class="dataframe">

how should I render this table? Is it easily possible?

Thank you!

1 Answer 1

1

Basically Express's res.render ends the response; which means we can only use it once, and it seems like the listener pyshell.on('message'... is being triggered more than once.

You will need to prepare the table then render it. Example:

const express = require('express');
const app = express();
const { PythonShell } = require('python-shell');

app.set('view engine', 'ejs');

app.get('/', function(req, res){
  prepareHtmlTable(function(err, html) {
    if (err) return res.sendStatus(500);
    res.render('list', { table: html });
  })
});

function prepareHtmlTable(callback) {
  const pyshell = new PythonShell('excel_to_html.py');

  pyshell.on('message', function (message) {
    // prepare html table here
    let html = message;

    pyshell.end(function (err,code,signal) {
      if (err) return callback(err);

      callback(null, html);
    });
  });
}

const port = 3000;
app.listen(port, function(){
  console.log('Server running on port ' + port)
});
Sign up to request clarification or add additional context in comments.

1 Comment

That worked! Since the listener is being triggered many times i only had to add html = html + message; and change the ejs placeholder to <%- table %> instead of <%= table %>. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.