8.8 KiB
Funcionalidade de Manipulação de PDFs
Visão Geral
Sistema completo de manipulação de arquivos PDF com as seguintes funcionalidades:
Recursos Implementados
-
Compressão de PDF sem perda de qualidade
- Compressão inteligente mantendo qualidade entre 50-100%
- Remoção de metadados desnecessários
- Otimização de streams de objetos
- Suporte para múltiplos arquivos simultâneos
-
Divisão de PDF
- Por páginas específicas (ex: 1,3,5,7)
- Por intervalos (ex: 1-5, 6-10)
- Por chunks de tamanho fixo
-
Mesclagem de PDFs
- Combine até 50 PDFs em um único arquivo
- Preserva qualidade original
- Ordem personalizável
-
PDF para Imagens
- Formatos: PNG, JPG, WEBP
- DPI ajustável (150-600)
- Qualidade configurável (50-100%)
- Conversão de páginas específicas ou todas
-
Imagens para PDF
- Suporta múltiplas imagens (até 100)
- Ajuste automático ao tamanho da página
- Suporta PNG, JPG, JPEG, WEBP
-
OCR (Reconhecimento Ótico de Caracteres)
- Extração de texto de PDFs escaneados
- Suporte para Português, Inglês e Espanhol
- Retorna confiança da extração
- Processamento por página
-
Informações do PDF
- Número de páginas
- Tamanho do arquivo
- Metadados (título, autor, criador, etc.)
- Datas de criação e modificação
Instalação
1. Instalar Dependências
npm install pdf-lib pdf-parse pdf2pic tesseract.js
npm install --save-dev @types/pdf-parse
Ou execute o script de instalação:
npm run install-pdf-deps
2. Executar Migration do Banco de Dados
npm run prisma:migrate
Ou manualmente:
npx prisma migrate dev --name add_operacoes_pdf
3. Gerar Cliente Prisma
npm run prisma:generate
4. Criar Diretórios Necessários
Os diretórios serão criados automaticamente na primeira execução, mas você pode criá-los manualmente:
mkdir -p storage/temp/pdf-ops
mkdir -p storage/pdf-output
mkdir -p storage/temp/uploads
Uso
Frontend
Acesse a página de manipulação de PDFs através da rota:
/pdf
API Endpoints
Todas as rotas requerem autenticação via Bearer token.
1. Comprimir PDF
POST /api/pdf/compress
Content-Type: multipart/form-data
Authorization: Bearer {token}
Body:
- files: File[] (array de PDFs)
- quality: number (50-100, padrão 95)
- maxSizeMB: number (opcional)
2. Dividir PDF
POST /api/pdf/split
Content-Type: multipart/form-data
Authorization: Bearer {token}
Body:
- files: File (único PDF)
- splitType: 'pages' | 'range' | 'chunks'
- pages: string (ex: "1,2,3") - para splitType='pages'
- ranges: string (ex: "1-5,6-10") - para splitType='range'
- chunkSize: number - para splitType='chunks'
3. Mesclar PDFs
POST /api/pdf/merge
Content-Type: multipart/form-data
Authorization: Bearer {token}
Body:
- files: File[] (mínimo 2 PDFs)
4. PDF para Imagens
POST /api/pdf/pdf-to-images
Content-Type: multipart/form-data
Authorization: Bearer {token}
Body:
- files: File (único PDF)
- format: 'png' | 'jpg' | 'webp' (padrão: png)
- quality: number (50-100, padrão: 95)
- density: number (DPI, 150-600, padrão: 300)
- pages: string (opcional, ex: "[1,2,3]" ou "all")
5. Imagens para PDF
POST /api/pdf/images-to-pdf
Content-Type: multipart/form-data
Authorization: Bearer {token}
Body:
- files: File[] (array de imagens)
- fitToPage: boolean (padrão: true)
- pageSize: string (opcional, JSON: {"width":595,"height":842})
6. OCR
POST /api/pdf/ocr
Content-Type: multipart/form-data
Authorization: Bearer {token}
Body:
- files: File (único PDF)
- language: string ('por' | 'eng' | 'spa', padrão: 'por')
- pages: string (opcional, ex: "[1,2]" ou "all")
7. Informações do PDF
POST /api/pdf/info
Content-Type: multipart/form-data
Authorization: Bearer {token}
Body:
- files: File (único PDF)
8. Histórico de Operações
GET /api/pdf/history?page=1&limit=20
Authorization: Bearer {token}
9. Download de Arquivo Processado
GET /api/pdf/download/:operacaoId/:fileIndex
Authorization: Bearer {token}
Estrutura de Resposta
Sucesso (Compressão)
{
"success": true,
"operacaoId": "uuid",
"results": [
{
"originalName": "documento.pdf",
"originalSize": 1048576,
"compressedSize": 524288,
"reduction": 50.0,
"outputPath": "/path/to/compressed.pdf"
}
],
"totalOriginalSize": 1048576,
"totalCompressedSize": 524288,
"totalReduction": 50.0,
"processingTime": 1234
}
Sucesso (OCR)
{
"success": true,
"operacaoId": "uuid",
"result": {
"text": "Texto extraído completo...",
"confidence": 95.5,
"pages": [
{
"pageNumber": 1,
"text": "Texto da página 1...",
"confidence": 96.2
}
]
},
"processingTime": 5678
}
Erro
{
"error": "Falha ao processar arquivo",
"message": "Detalhes específicos do erro"
}
Modelo de Dados
OperacaoPDF
interface OperacaoPDF {
id: string;
tipoOperacao: 'COMPRIMIR' | 'DIVIDIR' | 'MESCLAR' | 'PDF_PARA_IMAGEM' | 'IMAGEM_PARA_PDF' | 'OCR';
status: 'PROCESSANDO' | 'CONCLUIDO' | 'ERRO';
usuarioId: string;
arquivosOriginais: string[];
arquivosResultado: string[];
tamanhoOriginal: bigint;
tamanhoResultado: bigint | null;
parametros: any;
mensagemErro: string | null;
detalhesOCR: any | null;
tempoProcessamento: number | null;
criadoEm: Date;
atualizadoEm: Date;
}
Segurança
- ✅ Autenticação obrigatória em todas as rotas
- ✅ Validação de tipos de arquivo (apenas PDF e imagens)
- ✅ Limite de tamanho de arquivo (100MB por arquivo)
- ✅ Limite de quantidade de arquivos por operação
- ✅ Sanitização de nomes de arquivo
- ✅ Isolamento de arquivos por operação
- ✅ Limpeza automática de arquivos temporários
Performance
- ✅ Processamento assíncrono
- ✅ Otimização de memória com streams
- ✅ Compressão sem perda de qualidade perceptível
- ✅ Cache de workers de OCR
- ✅ Índices no banco de dados para consultas rápidas
- ✅ Limpeza automática de arquivos antigos
Tratamento de Erros
Todos os erros são:
- Logados no console do servidor
- Registrados no banco de dados (tabela operacoes_pdf)
- Retornados ao cliente com mensagens descritivas
- Capturados por try-catch em todas as operações
Limitações
- Tamanho máximo por arquivo: 100MB
- Máximo de arquivos para compressão: 10
- Máximo de arquivos para mesclagem: 50
- Máximo de imagens para conversão em PDF: 100
- Arquivos processados são mantidos por 24 horas
Manutenção
Limpeza de Arquivos Antigos
Execute periodicamente (recomendado: diariamente via cron):
import { PDFService } from './src/services/pdfService';
// Remove arquivos com mais de 24 horas
await PDFService.cleanupOldFiles(24);
Monitoramento
Consulte a tabela operacoes_pdf para:
- Estatísticas de uso
- Taxa de erro
- Tempo médio de processamento
- Operações mais utilizadas
-- Operações por tipo
SELECT "tipoOperacao", COUNT(*) as total
FROM operacoes_pdf
GROUP BY "tipoOperacao"
ORDER BY total DESC;
-- Taxa de sucesso
SELECT
status,
COUNT(*) as total,
ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER(), 2) as percentual
FROM operacoes_pdf
GROUP BY status;
-- Tempo médio por operação
SELECT
"tipoOperacao",
AVG("tempoProcessamento") as tempo_medio_ms,
MIN("tempoProcessamento") as tempo_min_ms,
MAX("tempoProcessamento") as tempo_max_ms
FROM operacoes_pdf
WHERE status = 'CONCLUIDO'
GROUP BY "tipoOperacao";
Troubleshooting
Erro: "Tesseract worker failed"
Solução: Certifique-se de que o Tesseract está instalado corretamente:
npm install tesseract.js --force
Erro: "Cannot find module 'sharp'"
Solução: Reinstale o Sharp com rebuild:
npm uninstall sharp
npm install sharp
npm rebuild sharp
Erro: "ENOSPC: no space left on device"
Solução: Aumente o espaço em disco ou execute a limpeza:
npm run cleanup-pdf-files
Performance lenta no OCR
Solução: Reduza o DPI ou processe menos páginas por vez.
Suporte
Para questões ou problemas:
- Verifique os logs do servidor
- Consulte a tabela
operacoes_pdfpara detalhes do erro - Verifique se os diretórios de storage têm permissões corretas
- Certifique-se de que todas as dependências estão instaladas
Changelog
v1.0.0 (2026-02-27)
- ✅ Implementação inicial
- ✅ Compressão sem perda de qualidade
- ✅ Divisão de PDFs
- ✅ Mesclagem de PDFs
- ✅ Conversão PDF para imagens
- ✅ Conversão de imagens para PDF
- ✅ OCR com Tesseract
- ✅ Histórico de operações
- ✅ Interface React completa
- ✅ Validação e segurança