0.0.2 • Published 6 months ago
@opens/docgen v0.0.2
Docgen
Uma biblioteca TypeScript para geração de documentos em vários formatos como PDF, Excel e CSV.
Instalação
npm install @opens/docgen
ou
yarn add @opens/docgen
Recursos
- Geração de documentos em formatos:
- Excel
- CSV
- Criação de tabelas com dados estruturados
- Customização de estilo e formatação
- Suporte para streaming para processamento eficiente de grandes volumes de dados
- Integração com serviços de armazenamento como Amazon S3
Como Usar
Importação
import {
DocumentGenerator,
DocumentTable,
DocumentFormat
} from '@opens/docgen';
Exemplo Básico
import { createWriteStream } from 'fs';
import {
DocumentGenerator,
DocumentTable,
DocumentFormat,
ColumnDefinition
} from '@opens/docgen';
// Função geradora que produz os elementos do documento
function* relatorioVendasGenerator() {
// Definição das colunas para nossa tabela
const columns: ColumnDefinition[] = [
{ field: 'produto', header: 'Produto' },
{ field: 'quantidade', header: 'Quantidade' },
{ field: 'valorUnitario', header: 'Valor Unitário (R$)' },
{ field: 'valorTotal', header: 'Valor Total (R$)' },
{ field: 'data', header: 'Data da Venda' }
];
// Dados de exemplo para a tabela
const dadosVendas = [
{
produto: 'Notebook Dell XPS 13',
quantidade: 5,
valorUnitario: 8500.00,
valorTotal: 42500.00,
data: '15/01/2025'
},
{
produto: 'Monitor LG Ultrawide',
quantidade: 8,
valorUnitario: 2200.00,
valorTotal: 17600.00,
data: '22/01/2025'
},
{
produto: 'Teclado Mecânico Logitech',
quantidade: 12,
valorUnitario: 450.00,
valorTotal: 5400.00,
data: '07/02/2025'
},
{
produto: 'Mouse sem fio Logitech',
quantidade: 15,
valorUnitario: 180.00,
valorTotal: 2700.00,
data: '14/02/2025'
},
{
produto: 'Headset HyperX',
quantidade: 10,
valorUnitario: 350.00,
valorTotal: 3500.00,
data: '28/02/2025'
}
];
// Criação do elemento de tabela com os dados e configurações
const tabelaVendas = new DocumentTable({
columns,
data: dadosVendas,
header: true,
title: 'Vendas do Primeiro Trimestre de 2025',
footer: 'Relatório gerado automaticamente em ' + new Date().toLocaleDateString('pt-BR')
});
// Retorna o elemento para o gerador de documentos
yield tabelaVendas;
}
// Função principal para gerar o relatório
async function gerarRelatorioDeVendas() {
try {
// Cria um stream para o arquivo de saída
const outputStream = createWriteStream('./relatorio-vendas.pdf');
// Configura o formato do documento
const config = {
format: DocumentFormat.PDF,
};
// Instancia o gerador de documentos
const generator = new DocumentGenerator(config, outputStream);
// Gera o documento utilizando nossa função geradora
await generator.generate(relatorioVendasGenerator);
console.log('Relatório de vendas gerado com sucesso!');
} catch (error) {
console.error('Erro ao gerar relatório:', error);
}
}
Integração com Amazon S3
Enviando documentos diretamente para o S3
import { PassThrough } from 'stream';
import { S3Client, Upload } from '@aws-sdk/client-s3';
import {
DocumentGenerator,
DocumentTable,
DocumentFormat
} from '@opens/docgen';
function* relatorioFuncionariosGenerator() {
// Definir colunas e dados
const columns = [
{ field: 'nome', header: 'Nome' },
{ field: 'departamento', header: 'Departamento' },
{ field: 'cargo', header: 'Cargo' }
];
const funcionarios = [
{ nome: 'Ana Silva', departamento: 'Vendas', cargo: 'Gerente Regional' },
{ nome: 'Carlos Mendes', departamento: 'TI', cargo: 'Desenvolvedor Sênior' },
{ nome: 'Juliana Costa', departamento: 'Marketing', cargo: 'Analista de Mídias Sociais' }
];
// Criar tabela
const tabela = new DocumentTable({
columns,
data: funcionarios,
header: true,
title: 'Relatório de Funcionários',
footer: 'Gerado em ' + new Date().toLocaleDateString('pt-BR')
});
yield tabela;
}
async function gerarEEnviarParaS3() {
try {
// Configuração do cliente S3
const s3Client = new S3Client({
region: 'sa-east-1',
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID || '',
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || ''
}
});
// Criação de um stream de passagem (passthrough)
const passThrough = new PassThrough();
// Configurar o upload para o S3 (iniciará automaticamente quando dados forem escritos)
const uploadParams = {
Bucket: 'minha-empresa-relatorios',
Key: `relatorio-funcionarios-${Date.now()}.pdf`,
Body: passThrough,
ContentType: 'application/pdf'
};
// Iniciar o upload
const uploadPromise = new Upload({
client: s3Client,
params: uploadParams
}).done();
// Configurar o gerador de documentos com o stream de passagem
const generator = new DocumentGenerator({
format: DocumentFormat.PDF,
options: {
orientation: 'portrait',
title: 'Relatório para S3'
}
}, passThrough);
// Gerar documento (os dados fluirão automaticamente para o S3 via passthrough)
await generator.generate(relatorioFuncionariosGenerator);
// Aguardar até que o upload seja concluído
const uploadResult = await uploadPromise;
console.log('Documento enviado com sucesso para o S3:', uploadResult);
return uploadResult;
} catch (error) {
console.error('Erro ao enviar para o S3:', error);
throw error;
}
}
Geração de Diferentes Formatos
const pdfConfig = {
format: DocumentFormat.PDF,
options: {
orientation: 'portrait'
}
};
Excel
const excelConfig = {
format: DocumentFormat.EXCEL,
options: {
sheetName: 'Dados',
}
};
CSV
const csvConfig = {
format: DocumentFormat.CSV,
options: {
filename: 'relatorio.csv'
}
};
Parâmetro Header nas Tabelas
O parâmetro header
nas tabelas é utilizado para controlar a exibição do cabeçalho:
// Com cabeçalho (default)
const tableWithHeader = new DocumentTable({
columns,
data,
header: true // Irá incluir o cabeçalho da tabela
});
// Sem cabeçalho - útil quando adicionando múltiplas tabelas que formam uma só
const tableWithoutHeader = new DocumentTable({
columns,
data,
header: false // Não incluirá o cabeçalho, apenas os dados
});
Quando utilizado como false
, o cabeçalho da tabela não será incluído, o que é útil em cenários onde:
- Você está adicionando múltiplas tabelas que representam partes de uma mesma tabela lógica
- Você deseja adicionar dados a uma tabela existente sem repetir o cabeçalho
Trabalhando com Streaming
Para arquivos grandes ou geração sob demanda:
import { createWriteStream } from 'fs';
import { DocumentGenerator, DocumentTable, DocumentFormat } from '@opens/docgen';
async function* relatorioStreamingGenerator() {
// Definição de colunas
const yourColumns = [
{ field: 'id', header: 'ID' },
{ field: 'nome', header: 'Nome' },
{ field: 'valor', header: 'Valor (R$)' },
{ field: 'data', header: 'Data de Registro' }
];
// Simulação de busca de dados em lotes
const batchSize = 100;
for (let i = 0; i < 1000; i += batchSize) {
const rows = await fetchDataBatch(i, batchSize); // Função fictícia para buscar dados
// Primeira parte com cabeçalho
if (i === 0) {
const tableWithHeader = new DocumentTable({
columns: yourColumns,
data: rows,
header: true, // Primeira parte inclui cabeçalho
title: 'Relatório de Dados em Streaming',
});
yield tableWithHeader;
} else {
// Partes subsequentes sem cabeçalho
const tableWithoutHeader = new DocumentTable({
columns: yourColumns,
data: rows,
header: false // Partes subsequentes não incluem cabeçalho
});
yield tableWithoutHeader;
}
}
}
async function gerarRelatorioStreaming() {
try {
const outputStream = createWriteStream('./relatorio-streaming.pdf');
const generator = new DocumentGenerator({
format: DocumentFormat.PDF,
options: {
orientation: 'landscape',
title: 'Relatório de Dados em Lotes'
}
}, outputStream);
await generator.generate(relatorioStreamingGenerator);
console.log('Relatório em streaming gerado com sucesso!');
} catch (error) {
console.error('Erro ao gerar relatório em streaming:', error);
}
}
Tipos Disponíveis
A biblioteca exporta vários tipos úteis:
import {
// Tipos principais
ColumnDefinition,
DocumentConfiguration,
BaseElement,
ElementType,
DocumentFormat,
// Tipos para estilos
ElementStyling,
TextAlignment,
PageOrientation,
// Configurações específicas para formatos
PDFDocumentSettings,
ExcelDocumentSettings,
CSVDocumentSettings,
// Tipos para elementos específicos
PDFTableElementData,
ExcelTableElementData,
CSVTableElementData,
} from '@opens/docgen';
Estrutura de ColumnDefinition
interface ColumnDefinition {
field: string; // A chave do campo nos dados
header: string; // O texto que aparecerá no cabeçalho
width?: number; // Largura opcional da coluna
}
Configurações por formato
// Configurações para PDF
interface PDFDocumentSettings {
orientation?: PageOrientation; // 'portrait' ou 'landscape'
title?: string; // Título do documento
subtitle?: string; // Subtítulo do documento
}
// Configurações para Excel
interface ExcelDocumentSettings {
sheetName?: string; // Nome da planilha
}
// Configurações para CSV
interface CSVDocumentSettings {
delimiter?: string; // Caractere delimitador
}
Licença
Este projeto está licenciado sob a licença MIT - veja o arquivo LICENSE para mais detalhes.
Contribuições
Contribuições são bem-vindas! Sinta-se à vontade para abrir issues ou pull requests.