
Quando seu aplicativo React gera PDFs dinamicamente — uma fatura que precisa do logotipo da empresa, um relatório com um gráfico incorporado, um certificado com uma assinatura — você precisa posicionar imagens raster na página programaticamente. O JavaScript puro não consegue gravar na estrutura interna de um PDF, e montar um backend apenas para carimbar um logotipo é exagero para o que é, na verdade, uma tarefa do lado do cliente.
Spire.PDF for JavaScript compila um mecanismo PDF completo para WebAssembly, para que seu aplicativo React possa criar, editar e salvar PDFs inteiramente no navegador. Os arquivos passam por um sistema de arquivos virtual (VFS) no navegador; portanto, não há ida e volta pela rede. Com PdfImage e o método DrawImage do canvas da página, você controla exatamente onde e em qual tamanho cada imagem aparece.
Neste artigo, você aprenderá a:
- Carregar uma imagem no VFS e transformá-la em um objeto
PdfImage - Desenhá-la em uma página de PDF em uma posição e tamanho escolhidos
- Adicionar imagens a documentos PDF novos e existentes
- Dimensionar, centralizar e repetir imagens em várias páginas
- Acionar o download do PDF finalizado no navegador
Por que gerar PDFs no navegador
A alternativa usual é uma biblioteca no lado do servidor (iText, PDFBox e similares): o navegador envia os recursos, o servidor renderiza e o resultado retorna. Isso funciona, mas, para inserção de imagens, gera atrito:
- Latência — cada renderização espera uma ida e volta, o que pesa para arquivos grandes ou conexões lentas.
- Privacidade — os documentos e imagens de origem saem da máquina do usuário, um problema para qualquer informação sensível.
- Custo — a renderização de PDF consome muita CPU e não escala gratuitamente.
Com o Spire.PDF for JavaScript, todo o trabalho é executado no navegador por meio do WebAssembly. Depois que o módulo WASM é carregado, a renderização é local e instantânea, o arquivo nunca sai do dispositivo e você não gasta nada com tempo de servidor.
Pré-requisitos
Este tutorial pressupõe que você já tenha um projeto React com o Spire.PDF for JavaScript instalado e o módulo WASM inicializado. Caso contrário, siga primeiro Integrando o Spire.PDF for JavaScript em um Projeto React.
Você precisará de:
- Os arquivos
spire.pdf.base.jsespire.pdf.base.wasmna pastapublicdo seu projeto - O módulo WASM acessível via
window.wasmModule.spirepdf - Uma imagem para incorporar (PNG, JPEG etc.) colocada em um local de onde o VFS possa carregá-la
Adicionar uma imagem a um novo PDF
O cenário mais simples: criar um novo documento PDF e desenhar uma imagem na primeira página. As etapas principais são:
-
Carregar a imagem no VFS usando
window.spire.FetchFileToVFS -
Criar um
PdfDocumente adicionar uma página em branco -
Criar um
PdfImagea partir do arquivo carregado comPdfImage.FromFile -
Desenhar a imagem no canvas da página com
page.Canvas.DrawImage - Salvar e baixar o resultado
function App() {
const addImageToPdf = async () => {
// Get the Spire.PDF WASM module
const pdfModule = window.wasmModule?.spirepdf;
// Check if the WASM module is ready
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// Load the image into VFS
const inputImageName = 'TreePic.png';
await window.spire.FetchFileToVFS(inputImageName, "", `${process.env.PUBLIC_URL}/data/`);
// Create a PdfDocument object
let doc = new pdfModule.PdfDocument();
// Add a page
let page = doc.Pages.Add();
// Load the image and scale its display size proportionally
let image = pdfModule.PdfImage.FromFile(inputImageName);
let width = image.Width * 0.6;
let height = image.Height * 0.6;
// Calculate the horizontal center position and set the vertical position
let x = (page.Canvas.ClientSize.Width - width) / 2;
let y = 60;
// Draw the image at the specified position on the page
page.Canvas.DrawImage({ image: image, x: x, y: y, width: width, height: height });
// Define the output file name in PDF format
const outputFileName = 'AddImage.pdf';
// Save as PDF format
doc.SaveToFile({ fileName: outputFileName });
doc.Close();
// Read the generated PDF file from VFS and trigger download
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Add Image To PDF</h1>
<button onClick={addImageToPdf}>
Generate
</button>
</div>
);
}
export default App;
Documento PDF gerado após adicionar uma imagem

O que o código faz:
-
PdfImage.FromFile(inputImageName)lê a imagem do VFS e cria um objetoPdfImage. As dimensões originais em pixels estão disponíveis por meio deimage.Widtheimage.Height. -
page.Canvas.DrawImage(...)renderiza a imagem na página. Os parâmetrosxeydefinem a posição do canto superior esquerdo, ewidtheheightcontrolam o tamanho de exibição. - A imagem é dimensionada para 60% do tamanho original (
* 0.6) e centralizada horizontalmente usando(page.Canvas.ClientSize.Width - width) / 2.
Adicionar uma imagem a um PDF existente
Adicionar uma imagem a um documento existente segue o mesmo padrão — a única diferença é que, em vez de criar um novo PdfDocument, você carrega um do VFS e seleciona a página de destino.
const addImageToExistingPdf = async () => {
const pdfModule = window.wasmModule?.spirepdf;
if (!pdfModule) return;
// Load both the PDF and the image into VFS
await window.spire.FetchFileToVFS('Report.pdf', "", `${process.env.PUBLIC_URL}/data/`);
await window.spire.FetchFileToVFS('Logo.png', "", `${process.env.PUBLIC_URL}/data/`);
// Load the existing PDF
let doc = new pdfModule.PdfDocument();
doc.LoadFromFile('Report.pdf');
// Get the first page (or any page you want)
let page = doc.Pages.get_Item(0);
// Load the image and draw it at the top-right corner
let image = pdfModule.PdfImage.FromFile('Logo.png');
let imgWidth = 80;
let imgHeight = 40;
let x = page.Canvas.ClientSize.Width - imgWidth - 30; // 30pt margin from right edge
let y = 30; // 30pt from top
page.Canvas.DrawImage({ image: image, x: x, y: y, width: imgWidth, height: imgHeight });
// Save and download
const outputFileName = 'ReportWithLogo.pdf';
doc.SaveToFile({ fileName: outputFileName });
doc.Close();
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
Diferença principal em relação ao exemplo de novo documento: doc.LoadFromFile('Report.pdf') carrega um PDF existente em vez de começar do zero, e doc.Pages.get_Item(0) recupera uma página do documento carregado. O restante da lógica de desenho é idêntico.
Quando a página já contém uma imagem que você precisa alterar em vez de sobrepor uma nova, consulte Substituindo e Removendo Imagens de PDFs em JavaScript (React).
Escala e posicionamento
O método DrawImage oferece a você controle total sobre onde e em qual tamanho a imagem aparece. Aqui estão os padrões mais comuns:
Dimensionamento proporcional — multiplique as duas dimensões pelo mesmo fator para preservar a proporção:
let scale = 0.5; // 50% of original size
let width = image.Width * scale;
let height = image.Height * scale;
Largura fixa, altura automática — defina a largura e calcule a altura para preservar a proporção:
let targetWidth = 200;
let width = targetWidth;
let height = image.Height * (targetWidth / image.Width);
Centralização horizontal — posicione a imagem a uma distância igual das margens esquerda e direita da página:
let x = (page.Canvas.ClientSize.Width - width) / 2;
Centralização vertical — posicione a imagem a uma distância igual do topo e da base da página:
let y = (page.Canvas.ClientSize.Height - height) / 2;
Posição personalizada — use coordenadas absolutas (a origem é o canto superior esquerdo; as unidades são pontos; 1 ponto = 1/72 de polegada):
let x = 72; // 1 inch from left
let y = 144; // 2 inches from top
Adicionar imagens a várias páginas
Para adicionar a mesma imagem (por exemplo, um logotipo ou marca d'água) a todas as páginas de um documento, percorra a coleção Pages:
const addImageToAllPages = async () => {
const pdfModule = window.wasmModule?.spirepdf;
if (!pdfModule) return;
await window.spire.FetchFileToVFS('Business_Data_Overview.pdf', "", `${process.env.PUBLIC_URL}/data/`);
await window.spire.FetchFileToVFS('Logo.png', "", `${process.env.PUBLIC_URL}/data/`);
let doc = new pdfModule.PdfDocument();
doc.LoadFromFile('Business_Data_Overview.pdf');
let image = pdfModule.PdfImage.FromFile('Logo.png');
let imgWidth = 60;
let imgHeight = 30;
// Loop through all pages and draw the logo in the top-right corner
for (let i = 0; i < doc.Pages.Count; i++) {
let page = doc.Pages.get_Item(i);
let x = page.Canvas.ClientSize.Width - imgWidth - 20;
let y = 20;
page.Canvas.DrawImage({ image: image, x: x, y: y, width: imgWidth, height: imgHeight });
}
const outputFileName = 'AllPagesWithLogo.pdf';
doc.SaveToFile({ fileName: outputFileName });
doc.Close();
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
Esse padrão é útil para adicionar marcas d'água, logotipos de empresa ou carimbos de página de forma uniforme em um documento com várias páginas.
Baixar o resultado
Depois de salvar o PDF no VFS com doc.SaveToFile(), você precisa lê-lo novamente e acionar o download no navegador. Esse padrão de duas etapas — salvar no VFS e, depois, ler do VFS — é usado em todos os exemplos do Spire.PDF for JavaScript:
// 1. Save the PDF to the VFS
doc.SaveToFile({ fileName: 'Output.pdf' });
doc.Close();
// 2. Read the file from VFS as a byte array
const fileArray = window.dotnetRuntime.Module.FS.readFile('Output.pdf');
// 3. Create a Blob and trigger download
const blob = new Blob([fileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'Output.pdf';
a.click();
URL.revokeObjectURL(url);
O mesmo padrão se aplica ao salvar imagens (use type: 'image/png' ou type: 'image/jpeg' no construtor do Blob).
Perguntas frequentes
Como controlo com precisão a posição e o tamanho de uma imagem?
Os parâmetros x e y de DrawImage definem as coordenadas do canto superior esquerdo da imagem (em pontos, em que 1 ponto = 1/72 de polegada). Os parâmetros width e height definem o tamanho de exibição. Para dimensionar proporcionalmente, leia image.Width e image.Height e multiplique ambos pelo mesmo fator. Para centralizar horizontalmente, calcule x = (page.Canvas.ClientSize.Width - width) / 2.
Posso adicionar várias imagens à mesma página?
Sim. Chame page.Canvas.DrawImage(...) uma vez para cada imagem, com coordenadas x/y diferentes. As imagens são desenhadas na ordem em que você chama o método; portanto, as imagens posteriores aparecem por cima das anteriores se houver sobreposição.
Quais formatos de imagem são suportados?
O Spire.PDF for JavaScript suporta formatos raster comuns, incluindo PNG, JPEG, BMP e GIF. Use PdfImage.FromFile(filename) para carregar qualquer um deles do VFS.
Adicionar uma imagem afeta o conteúdo existente na página?
Não. DrawImage adiciona um novo objeto de imagem à página sem modificar textos, gráficos ou outras imagens existentes. A imagem é desenhada sobre o conteúdo existente nas coordenadas especificadas. Para extrair uma imagem de um PDF existente e reutilizá-la em outro lugar, consulte Extrair imagens de um PDF em JavaScript (React).