Conoce la tierra.
Fotografie de Nicolas Lobos / Unsplash

Înțelegerea internă a NodeJS poate fi puțin descurajantă (știu că a fost pentru mine odată). Nodul este un limbaj foarte puternic și poate face multe lucruri.

Astăzi am vrut să descopăr puterea instrumentului utilitar încorporat Node numit fs (Sistemul de fișiere)

Conform fs documente:

fs Modulul oferă un API pentru interacțiunea cu sistemul de fișiere într-o manieră strâns modelată în funcție de funcțiile POSIX standard.

Care este doar un mod fantezist de a spune asta Sistemul de fișiere este o modalitate în Node de a interacționa cu fișiere atât pentru operații de citire cât și de scriere.

Acum Sistemul de fișiere este un utilitar imens în NodeJS care are o mulțime de caracteristici fanteziste. Cu toate acestea, în acest articol voi discuta doar 3:

  • Obținerea informațiilor despre fișier: fs.statSync
  • Ștergerea unui fișier: fs.unlinkSync
  • Scrierea datelor într-un fișier: fs.writeFileSync

Un alt lucru pe care îl vom acoperi în acest articol este Google Puppeteer care este acest instrument foarte interesant, creat de câțiva oameni minunați de la Google.

Deci, ce este păpușarul? Ei bine, conform documentelor, ei spun:

Puppeteer este o bibliotecă de noduri care oferă un API de nivel înalt de controlat fără cap Chrome sau Chromium peste Protocolul DevTools. De asemenea, poate fi configurat pentru a utiliza Chrome sau Chromium complet (fără cap).

Deci, este practic un instrument care vă permite să faceți toate lucrurile interesante legate de browser pe server. De exemplu, obținerea capturilor de ecran ale unui site web, accesarea cu crawlere a site-urilor web și generarea de conținut pre-render pentru aplicații cu o singură pagină. Puteți face chiar trimiteri de formulare prin serverul dvs. NodeJS.

Din nou păpușarul este un instrument imens, așa că vom acoperi doar o caracteristică mică, dar foarte interesantă a păpușarului. Ne vom uita cum să generăm un fișier PDF frumos pe baza fișierului nostru de tabel HTML generat. În acest proces vom învăța despre puppeteer.launch () și vom înțelege puțin despre pagina () și pdf ().

Deci, pentru a oferi din nou o scurtă prezentare generală, lucrurile pe care le vom acoperi:

  • Generarea de date stub (pentru facturi) folosind un instrument online.
  • Crearea unui tabel HTML cu un pic de stil cu datele generate în el, folosind un script nod automatizat.
  • Aflați despre verificarea dacă există un fișier sau nu folosind fs.statSync
  • Aflați despre ștergerea unui fișier utilizând fs.unlinkSync
  • Aflați despre scrierea unui fișier folosind fs.writeFileSync
  • Crearea unui fișier PDF al fișierului HTML generat cu ajutorul păpușarului Google
  • Transformarea lor în scripturi npm, pentru a fi utilizate mai târziu? ?

De asemenea, înainte de a începe aici este întregul codul sursă al tutorialului, pentru ca toți să urmeze. Nu trebuie să scrieți nimic, dar ar trebui să scrieți cod împreună cu acest tutorial. Acest lucru se va dovedi mai util și veți înțelege mai multe. CODUL SURSEI DE TUTORIAL

Înainte de a începe, vă rugăm să vă asigurați că aveți cel puțin următoarele elemente instalate pe aparatul dvs.

  • Versiunea nodului 8.11.2
  • Node Package Manager (NPM) versiunea 6.9.0

Nu este nevoie, dar puteți viziona și un videoclip introductiv (primul meu realizat vreodată) care vorbește despre elementele de bază ale citirii, scrierii și ștergerii unui fișier în NodeJS. Acest lucru vă va ajuta să înțelegeți acest tutorial. (Vă rog să-mi dați feedback). ?

Să începem

Pasul 1:

În terminalul dvs. introduceți următoarele:

npm init -y

Aceasta va inițializa un proiect gol pentru dvs.

Pasul 2:

În al doilea rând, în același folder, creați un fișier nou numit data.json și să aibă niște date batjocorite. Puteți utiliza următorul exemplu JSON.

Puteți obține datele JUB șterse de la Aici. Pentru generarea acestor date am folosit un instrument minunat numit https://mockaroo.com/ Este un instrument de generare de date online.

Datele JSON cu care merg au o structură de genul acesta:

[
  {},
  {},
  {
   "invoiceId": 1,
   "createdDate": "3/27/2018",
   "dueDate": "5/24/2019",
   "address": "28058 Hazelcrest Center",
   "companyName": "Eayo",
   "invoiceName": "Carbonated Water - Peach",
   "price": 376
  },
  {
   "invoiceId": 2,
   "createdDate": "6/14/2018",
   "dueDate": "11/14/2018",
   "address": "6205 Shopko Court",
   "companyName": "Ozu",
   "invoiceName": "Pasta - Fusili Tri - Coloured",
   "price": 285
  },
  {},
  {}
]

Puteți descărca matricea completă JSON pentru acest tutorial de la Aici.

Pasul 3:

Apoi creați un fișier nou numit buildPaths.js

const path = require('path');
const buildPaths = {
   buildPathHtml: path.resolve('./build.html'),
   buildPathPdf: path.resolve('./build.pdf')
};
module.exports = buildPaths;

Asa de path.resolve va lua o cale relativă și ne va întoarce calea absolută a acelui director.

Asa de path.resolve('./build.html'); de exemplu va returna ceva de genul acesta:

$ C:\Users\Adeel\Desktop\articles\tutorial\build.html

Pasul 4:

În același folder creați un fișier numit createTable.js și adăugați următorul cod:

const fs = require('fs');
// JSON data
const data = require('./data.json');
// Build paths
const { buildPathHtml } = require('./buildPaths');

/**
 * Take an object which has the following model
 * @param {Object} item 
 * @model
 * {
 *   "invoiceId": `Number`,
 *   "createdDate": `String`,
 *   "dueDate": `String`,
 *   "address": `String`,
 *   "companyName": `String`,
 *   "invoiceName": `String`,
 *   "price": `Number`,
 * }
 * 
 * @returns {String}
 */
const createRow = (item) => `
  <tr>
    <td>${item.invoiceId}</td>
    <td>${item.invoiceName}</td>
    <td>${item.price}</td>
    <td>${item.createdDate}</td>
    <td>${item.dueDate}</td>
    <td>${item.address}</td>
    <td>${item.companyName}</td>
  </tr>
`;

/**
 * @description Generates an `html` table with all the table rows
 * @param {String} rows
 * @returns {String}
 */
const createTable = (rows) => `
  <table>
    <tr>
        <th>Invoice Id</td>
        <th>Invoice Name</td>
        <th>Price</td>
        <th>Invoice Created</td>
        <th>Due Date</td>
        <th>Vendor Address</td>
        <th>Vendor Name</td>
    </tr>
    ${rows}
  </table>
`;

/**
 * @description Generate an `html` page with a populated table
 * @param {String} table
 * @returns {String}
 */
const createHtml = (table) => `
  <html>
    <head>
      <style>
        table {
          width: 100%;
        }
        tr {
          text-align: left;
          border: 1px solid black;
        }
        th, td {
          padding: 15px;
        }
        tr:nth-child(odd) {
          background: #CCC
        }
        tr:nth-child(even) {
          background: #FFF
        }
        .no-content {
          background-color: red;
        }
      </style>
    </head>
    <body>
      ${table}
    </body>
  </html>
`;

/**
 * @description this method takes in a path as a string & returns true/false
 * as to if the specified file path exists in the system or not.
 * @param {String} filePath 
 * @returns {Boolean}
 */
const doesFileExist = (filePath) => {
	try {
		fs.statSync(filePath); // get information of the specified file path.
		return true;
	} catch (error) {
		return false;
	}
};

try {
	/* Check if the file for `html` build exists in system or not */
	if (doesFileExist(buildPathHtml)) {
		console.log('Deleting old build file');
		/* If the file exists delete the file from system */
		fs.unlinkSync(buildPathHtml);
	}
	/* generate rows */
	const rows = data.map(createRow).join('');
	/* generate table */
	const table = createTable(rows);
	/* generate html */
	const html = createHtml(table);
	/* write the generated html to file */
	fs.writeFileSync(buildPathHtml, html);
	console.log('Succesfully created an HTML table');
} catch (error) {
	console.log('Error generating table', error);
}
scriptul createTable.js (github gist: https://gist.github.com/adeelibr/70936277d38f3c77d3910e417581e98a#file-createtable-js)

Știu că este o mulțime de cod, dar hai să îl împărțim în bucăți și să începem să-l înțelegem bucată cu bucată.

Mergi la linia 106 (github gist)

În a noastră try/catch bloc verificăm mai întâi dacă fișierul de compilare pentru HTML există sau nu în sistem. Aceasta este calea fișierului în care scriptul nostru NodeJS va genera HTML-ul nostru.

if (doesFileExist(buildPathHtml){} apelează metoda doesFileExist () care returnează pur și simplu adevărat / fals. Pentru aceasta folosim

fs.statSync(filePath);

Această metodă returnează de fapt informații despre fișier, cum ar fi dimensiunea fișierului, când a fost creat fișierul și așa mai departe. Totuși, dacă îi oferim o cale de fișier nevalidă, această metodă revine ca o eroare nulă. Pe care le folosim aici în beneficiul nostru și înfășurăm fs.statSync() metoda într-un try/catch. Dacă Node poate citi cu succes fișierul din blocul nostru try, ne întoarcem true – altfel aruncă o eroare pe care o primim în blocul nostru de captură și o întoarce false.

Dacă fișierul există în sistem, vom șterge fișierul folosind

fs.unlinkSync(filePath); // takes in a file path & deletes it

După ștergerea fișierului, trebuie să generăm rânduri pe care să le punem în tabel.

Pasul 5:

Deci mai întâi importăm data.json la care facem linia 3 & apoi linia 115 iterăm fiecare articol folosind map (). Puteți citi mai multe despre Array.prototype.map () aici.

Metoda hărții ia o metodă createRow care preia un obiect prin fiecare iterație și returnează un șir care are un conținut de genul acesta:

"<tr>
  <td>invoice id</td>
  <td>invoice name</td>
  <td>invoice price</td>
  <td>invoice created date</td>
  <td>invoice due date</td>
  <td>invoice address</td>
  <td>invoice sender company name</td>
</tr>"

const row = data.map(createdRow).join('');

join('') partea este importantă aici, pentru că vreau să concatenez toată matrice într-un șir.

Un principiu aproape similar este utilizat pentru generarea unui tabel pe linia 117 & apoi tabelul html pe rândul 119.

Pasul 6:

Partea importantă este locul în care scriem în fișierul nostru linia 121:

fs.writeFileSync(buildPathHtml, html); 

Are 2 parametri: unul este calea de construire (șir) și conținutul html (șir) și generează un fișier (dacă nu este creat; iar dacă este creat, suprascrie fișierul deja existent).

Un lucru de reținut aici este posibil să nu avem nevoie de Pasul 4, unde verificăm dacă fișierul există și dacă îl șterge. Acest lucru se datorează faptului că writeFileSync face asta pentru noi. Tocmai am adăugat asta în cod în scopuri de învățare.

Pasul 7:

În terminalul dvs., accesați calea folderului unde aveți createTable.js și tastați

$ npm run ./createTable.js

De îndată ce rulați acest script, acesta va crea un fișier nou în același folder numit build.html Puteți deschide acel fișier în browserul dvs. și va arăta cam așa.

Cum se genereaza un tabel HTML si un PDF cu
Tabel HTML generat.

Cool nu? Până acum, bine. ?

De asemenea, puteți adăuga un npm script în package.json dvs. așa:

"scripts": {
  "build:table": "node ./createTable.js"
},

Astfel, în loc să scrie npm run ./createTable.js, puteți doar să tastați npm run build:table.

În continuare: generarea unui PDF din generat HTML fişier.

Pasul 8:

Mai întâi, trebuie să instalăm un instrument elegant, așa că intrați în terminalul dvs. din folderul aplicației și introduceți

npm install puppeteer

Pasul 9:

În același folder în care aveți fișiere createTable.js , buildPaths.js & data.json, creați un fișier nou numit createPdf.js și adăugați conținut la fel ca mai jos:


const fs = require('fs');
const puppeteer = require('puppeteer');
// Build paths
const { buildPathHtml, buildPathPdf } = require('./buildPaths');

const printPdf = async () => {
	console.log('Starting: Generating PDF Process, Kindly wait ..');
	/** Launch a headleass browser */
	const browser = await puppeteer.launch();
	/* 1- Ccreate a newPage() object. It is created in default browser context. */
	const page = await browser.newPage();
	/* 2- Will open our generated `.html` file in the new Page instance. */
	await page.goto(buildPathHtml, { waitUntil: 'networkidle0' });
	/* 3- Take a snapshot of the PDF */
	const pdf = await page.pdf({
		format: 'A4',
		margin: {
			top: '20px',
			right: '20px',
			bottom: '20px',
			left: '20px'
		}
	});
	/* 4- Cleanup: close browser. */
	await browser.close();
	console.log('Ending: Generating PDF Process');
	return pdf;
};

const init = async () => {
	try {
		const pdf = await printPdf();
		fs.writeFileSync(buildPathPdf, pdf);
		console.log('Succesfully created an PDF table');
	} catch (error) {
		console.log('Error generating PDF', error);
	}
};

init();
createPdf.js github gist

Așa cum am făcut cu createTable.js script, să descompunem acest lucru în bucăți și să începem să înțelegem acest script pas cu pas.

Sa incepem cu linia 40: aici numim o metodă init () care apelează metoda linia 30. unu lucru pe care să ne concentrăm este că metoda noastră init () este o metodă asincronizată. Citiți mai multe despre acest lucru funcția asincronă.

Mai întâi în metoda init () pe care o numim printPdf () care este din nou o metodă asincronă, deci trebuie să așteptăm răspunsul acesteia. Metoda printPdf () ne returnează o instanță PDF pe care o scriem apoi într-un fișier linia 33.

Deci, ce înseamnă printPdf() metoda nu? Să săpăm adânc în el.

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(buildPathHtml, { waitUntil: 'networkidle0' });
const pdf = await page.pdf({
  format: 'A4',
  margin: {
   top: '20px', right: '20px', bottom: '20px', left: '20px'}
});
await browser.close();
return pdf;

Mai întâi lansăm o instanță de browser fără cap folosind păpușar făcând următoarele:

await puppeteer.launch(); // this returns us headless browser

pe care apoi îl folosim pentru a deschide o pagină web:

await browser.newPage(); // open a blank page in headless browser

Odată ce avem o pagină goală deschisă, putem naviga la o pagină. Întrucât pagina noastră web este locală în sistemul nostru, noi pur și simplu

page.goto(buildPathHtml, { waitUntil: 'networkidle0' });

Aici waitUntil: 'networkidle0; este important, deoarece îi spune păpușarului să aștepte 500 / ms până când nu mai există conexiuni de rețea.

Notă: Acesta este motivul pentru care am folosit path.resolve () pentru a obține căi absolute, deoarece pentru a deschide pagina web cu păpușarul, avem nevoie de o cale absolută.

După ce avem o pagină web deschisă în browserul fără cap de pe server, salvăm acea pagină în format pdf:

await page.pdf({ });

De îndată ce avem o versiune pdf a paginii web, trebuie să închidem instanța de browser deschisă de păpușar pentru a economisi resurse procedând astfel:

await browser.close();

& apoi ne întoarcem pdf salvat, pe care îl scriem apoi în fișier.

Pasul 10:

În tipul de terminal

$ npm ./createPdf.js

Notă: Înainte de a rula scriptul de mai sus, asigurați-vă că build.html fișier generat de createTable.js scenariu. Acest lucru ne asigură că avem întotdeauna build.html înainte de a rula createPdf.js scenariu. În dumneavoastră package,json urmează următoarele instrucțiuni.

"scripts": {
  "build:table": "node ./createTable.js",
  "prebuild:pdf": "npm run build:table",
  "build:pdf": "node ./createPdf.js"
},

Acum dacă alergi $ npm run build:pdf va executa createTable.js scriptul mai întâi și apoi createPdf.js scenariu. Puteți citi mai multe pe Scripturi NPM pe oficialul lor documente.

Când alergi

$ npm run build:pdf

Acesta va rula și va crea un fișier build.pdf care va arăta astfel:

1612007049 173 Cum se genereaza un tabel HTML si un PDF cu
Fișier .pdf generat la rulare createPdf.js scenariu

Și atât, am terminat.

Ați învățat următoarele:

  • Cum se verifică dacă există un fișier / informații despre fișierul tet (în nod)
  • Cum să ștergeți un fișier în nod
  • Cum se scrie într-un fișier
  • Cum se folosește Google Puppeteer pentru a genera un fișier PDF

Învățare fericită, mi-ar plăcea să vă aud gândurile despre acest articol. Puteți ajunge la mine mai departe stare de nervozitate de asemenea.