Como extrair texto de arquivo pdf em NodeJs

Express 29 de Jun de 2021

Se você chegou até aqui, é por que está com a necessidade de extrair o texto de algum arquivo no formato PDF.

Recentemente eu também passei por isso, revirei a internet em busca da melhor lib e melhor prática para fazer esse trabalho.

Neste artigo eu vou te mostrar como fiz, quais tecnologias utilizei e práticas.

Criando o projeto NodeJs

Para começar, vamos criar um projeto nodejs simples utilizando um dos comandos abaixo:

yarn init
//ou
npm init

Agora vamos instalar as bibliotecas necessárias que são express e pdfjs-dist:

yarn add express pdfjs-dist
//ou 
npm install express pdfjs-dist

Com as libs instaladas, é hora de criar nosso servidor express.

Já aproveitando, já crie a rota app.get('/file/:filename/:password', async (req, res) => {}); que será utilizada mais para frente.

Crie um arquivo server.js na pasta do seu projeto e crie o servidor como abaixo:

const express = require('express');

const app = express();

const cors = require('cors');

app.use(cors());
app.use(express.json());

app.get('/ping', (req, res) => res.send('pong'));

app.get('/file/:filename/:password', async (req, res) => {
  // vamos extrair o pdf aqui
  res.send('...');
});

app.listen(3333); 

module.exports = app;

Classe para extrair o texto do PDF

Agora que já temos o servidor express criado, vamos criar um arquivo onde iremos escrever o código que irá de fato fazer a extração do texto do arquivo pdf. Aqui eu chamei esse arquivo de readerPDF2Text.js.

Esse arquivo deve ser assim:

const pdfjslib = require('pdfjs-dist/es5/build/pdf')


class Pdf {
  static async getPageText (pdf, pageNo) {
    const page = await pdf.getPage(pageNo)
    const tokenizedText = await page.getTextContent()

    const pageText = tokenizedText.items.map(token => token.str).join('')
    return pageText
  }

  static async getPDFText (source, password) {
    const pdf = await pdfjslib.getDocument({ data: source, password }).promise
    const maxPages = pdf.numPages

    const pageTextPromises = []
    for (let pageNo = 1; pageNo <= maxPages; pageNo += 1) {
      pageTextPromises.push(Pdf.getPageText(pdf, pageNo))
    }
    const pageTexts = await Promise.all(pageTextPromises)
    return pageTexts.join(' ')
  }
}

module.exports = Pdf

A biblioteca pdfjslib é a responsável por fazer o trabalho pesado 😍.

No arquivo server.js iremos chamar a função getPDFText() passando o diretório onde o pdf está em nosso servidor e a senha, caso o arquivo esteja protegido por uma.

Este exemplo usa um arquivo pdf que já está salvo em disco no servidor. Caso você precise enviar o arquivo pdf do seu front-end para extrair o texto, sugiro criar uma função para salvar seu arquivo em algum diretório do servidor express e sem seguida usar a função que criamos.

Chamando a função getPDFText

Para finalizar, vamos alterar o arquivo server.js para chamar a função getPDFText() e dar o retorno do texto do pdf para o front-end que fizer a requisição na rota /file/:filename/:password.

const express = require('express');

const Pdf = require('./readerPDF2text')
const fs = require('fs')

const app = express();

const cors = require('cors');

app.use(cors());
app.use(express.json());

app.get('/ping', (req, res) => res.send('pong'));

app.get('/file/:filename/:password', async (req, res) => {
	
  const fileBuffer = fs.readFileSync(req.params.filename);
  let pdfRow = null
  if (req.params.password){
	pdfRow = await Pdf.getPDFText(fileBuffer, req.params.password)
  }else {
	pdfRow = await Pdf.getPDFText(fileBuffer)
  }
  
  
  res.send(pdfRow);
  
});

app.listen(3333); 

module.exports = app;

Pronto!! Já finalizamos tudo que precisava. Agora basta rodar o servidor express e chamar a rota que criamos para ler o arquivo, passando o diretório e senha.

🟡 Vale lembrar que você não pode chamar sua rota que criamos (com route params) e passar o diretório do arquivo diretamente assim, por exemplo: c:\documents\file.pdf. Esse caminho precisa ser codificado para não gerar erro no servidor. Você pode ler mais sobre isso aqui: https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/encodeURI

Concluindo

Vou ficando por aqui espero ter ajudado. 😉

Ficou com alguma dúvida? fique a vontade para me chamar nos comentários!

Josias Pereira

Programador full-stack sênior e apaixonado por ensinar. No tempo livre adora compartilhar conhecimentos e experiências das tecnologias de desenvolvimento back-end e front-end que mais gosta.

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.