Files
hpos-web/scripts/pdf.js

282 lines
71 KiB
JavaScript
Raw Normal View History

2023-08-29 16:29:57 +05:30
var fs = require('fs');
const csv = require('csv-parser');
const moment = require('moment');
const html_to_pdf = require('html-pdf-node');
async function makePdf(data) {
let options = { format: 'A4' };
let template = {
content: `<!DOCTYPE html>
<head>
<style>
// @media print {
// body {
// -webkit-print-color-adjust: exact;
// }
// }
html { -webkit-print-color-adjust: exact; }
.person-details-row {
display: flex;
flex-direction: row;
}
.person-details-col {
display: flex;
flex-direction: column;
height: 90px;
width: 50%;
margin: 1px;
border: 0;
}
.test-details-row {
border: 0;
}
.test-details-col {
height: 100px;
}
.test-cell-div {
/* border: 1px solid black; */
border-collapse: collapse;
height: 20px;
padding: 10px;
}
.table-header {
border: 1px solid black;
margin: 0 0 -10px 10px;
background-color: rgb(191, 191, 191) !important;
text-align: center;
justify-content: center;
align-items: center;
display: flex;
font-weight: 600;
height: 50px;
width: 98%;
}
// @media print {
// .table-header {
// background-color: rgb(191, 191, 191) !important;
// print-color-adjust: exact;
// }
// }
// @media print {
// .vendorListHeading th {
// color: white !important;
// }
// }
.test-method {
font-weight: 200 !important;
color: rgb(191, 191, 191);
}
.result-value {
justify-content: center;
align-items: center;
display: flex;
}
.end-of-report {
display: flex;
align-items: center;
justify-content: center;
}
.logo {
display: flex;
justify-content: center;
align-items: center;
}
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
ul {
list-style-type: none;
/* margin: 0; */
/* padding: 0; */
}
</style>
</head>
<body>
<div>
<div class="logo">
<img src="data:image/png;base64,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
</div>
<table style="border: 1px solid black; margin: 10px; width: 98%;">
<tr class="person-details-row">
<td class="person-details-col" style="border-right: 2; width: 65%;">
<div><strong>Person Name:</strong> ${data?.Name} </div>
<div><strong>Age / Sex:</strong> ${data?.Age} / ${data?.Gender}</div>
<div><strong>Sample type:</strong> Capillary Whole Blood </div>
<div><strong>Family History of Sickle Cell Anemia:</strong> NA </div>
</td>
<td class="person-details-col" style="width: 35%;">
<div><strong>Marital Status:</strong> ${data["Marital Status"]} </div>
<div><strong>Test Date:</strong> ${data?.testTime} </div>
<div><strong>ABHA ID:</strong> ${data["ABHA ID"]} </div>
<div><strong>Sample ID:</strong> ${data["_id"]} </div>
</td>
</tr>
</table>
</div>
<div style="height: 2px;width: 98%; background-color: rgb(56, 105, 166); margin: 30px 10px 40px 10px;"></div>
<div>
<div class="table-header">POINT OF CARE SICKLE CELL ANEMIA TEST</div>
<table class="test-details-table" style="border: 1px solid black; margin: 10px; width: 98%;">
<tr style="height: 50px;">
<th>
Test Description
</th>
<th>
RESULT
</th>
<th>
REFERENCE RANGES
</th>
</tr>
<tr class="test-details-row">
<td class="test-details-col" style="width: 20%; margin: 10px;">
<div style="margin: 10px;"> Sickle Cell Anemia
<div class="test-method">(Method: HPOS)</div>
</div>
</td>
<td style="width: 30%;">
<div class="result-value">Ra = ${data["Test Right device 5 ratio"]} </div>
<!-- <div class="test-cell-div">Normal</div>
<div class="test-cell-div">Sickle Cell Trait</div>
<div class="test-cell-div">Sickle Cell Disease</div>
<div class="test-cell-div">Negative Borderline</div>
<div class="test-cell-div">Positive Borderline</div> -->
</td>
<td style="width: 50%;">
<div class="test-cell-div">
< 0.16: Normal (HbA)</div>
<div class="test-cell-div">0.165 0.235: Sickle-cell Trait (HbAS)</div>
<div class="test-cell-div">> 0.24: Sickle-cell Disease (HbSS)</div>
<div class="test-cell-div">0.16-0.165: Inconclusive (Negative Borderline)</div>
<div class="test-cell-div">0.235 0.24: Inconclusive (Positive Borderline)</div>
</td>
<!-- <td style="width: 25%;">
<div class="test-cell-div">Normal</div>
<div class="test-cell-div">Sickle Cell Trait</div>
<div class="test-cell-div">Sickle Cell Disease</div>
<div class="test-cell-div">Recommended for HPLC or Electrophoresis Tests</div>
<div class="test-cell-div">Recommended for HPLC or Electrophore</div>
</td> -->
</tr>
</table>
</div>
<div>
<!-- <div style="font-weight: 600; margin: 10px;">INTERPRETATION:</div> -->
<div style="margin: 10px;">
<strong>Test Principle:</strong> This point of care quantitative diagnostic test for sickle-cell anemia
works on the principle of absorption
spectroscopy. The test helps in differentiating heterozygous/homozygous hemoglobin from normal hemoglobin.
</div>
<div style="margin: 10px;">
<strong>Method:</strong> High Performance Optical Spectroscopy (HPOS) for detection of Sickle cell trait and
sickle cell disease in whole blood capillary blood samples.
</div>
<div style="margin: 10px;">
<strong> Note:</strong>
<!-- <ul>
<li>a. Blood transfusion may have an impact on the test results.</li>
<li>
b. Patients already on sickle-cell medications may impact test results.
</li>
</ul> -->
Borderline cases are reported as inconclusive. It may occur due to several factors such as medication,
transfusion, field conditions and assay process. Further clinical tests are recommended in these cases for
diagnosis.
</div>
<!-- <div
style="margin: 80px 10px 20px 50px; width: 88%; display: flex; flex-direction: row; justify-content: space-between; align-items: center;">
<div style="margin: 5px;">DATE:</div>
<div style="margin: 5px;">Hematologist</div>
</div> -->
<!-- <div style="margin: 30px;">
This report is for the perusal of doctor only. Not for medico legal cases. Clinical correlation is
essential.
Please contact us in case of unexpected result.
</div> -->
<div style="height: 3px;width: 98%; background-color: black; margin-top: 150px;"></div>
<div class="end-of-report">
*** END OF REPORT ***</div>
<div style="display: flex; justify-content: center; align-items: center; flex-direction: column;">
<div style="font-style: italic; color: rgb(191, 191, 191);">
This is an electronically generated report. Generated at ${moment().format('HH:MM')} hrs on ${moment().format('DD-MM-YYYY')}.
</div>
<div>
Note: Assay results should be correlated clinically with other clinical findings
</div>
</div>
</div>
</body>
</html>` };
html_to_pdf.generatePdf(template, options).then(pdfBuffer => {
fs.writeFile(`reports/${data._id}.pdf`, pdfBuffer, "binary", function (err) {
if (err) {
console.log(err);
} else {
console.log("The file was saved!");
}
});
});
}
const delay = (delayInms) => {
return new Promise(resolve => setTimeout(resolve, delayInms));
}
const users = [];
fs.createReadStream("data/result.csv")
.pipe(csv())
.on('data', function(data){
try {
console.log("id: " + data._id);
users.push(data);
}
catch(err) {
//error handler
}
})
.on('end', async function(){
console.log('size ', users.length);
for (let i = 0; i < users.length; i++) {
await makePdf(users[i]);
let delayres = await delay(10000);
console.log('index ', i);
}
});