updates
This commit is contained in:
@@ -223,106 +223,204 @@ const gerarPDFAvaliacao = async () => {
|
||||
const valor = respostas[p.id];
|
||||
linhasTabelaHtml += `
|
||||
<tr>
|
||||
<td style="text-align:center; border: 1px solid #000; padding: 2px;">${idx + 1}</td>
|
||||
<td style="text-align:left; border: 1px solid #000; padding: 4px;">${p.texto}</td>
|
||||
<td style="text-align:center; border: 1px solid #000; font-weight: bold;">${valor === 5 ? 'X' : ''}</td>
|
||||
<td style="text-align:center; border: 1px solid #000; font-weight: bold;">${valor === 4 ? 'X' : ''}</td>
|
||||
<td style="text-align:center; border: 1px solid #000; font-weight: bold;">${valor === 3 ? 'X' : ''}</td>
|
||||
<td style="text-align:center; border: 1px solid #000; font-weight: bold;">${valor === 2 ? 'X' : ''}</td>
|
||||
<td style="text-align:center; border: 1px solid #000; font-weight: bold;">${valor === 1 ? 'X' : ''}</td>
|
||||
<td style="text-align:center; border: 1px solid #000; padding: 2.5px; font-size: 8pt; font-weight: bold;">${idx + 1}</td>
|
||||
<td style="text-align:left; border: 1px solid #000; padding: 2.5px 5px; font-size: 8pt;">${p.texto}</td>
|
||||
<td style="text-align:center; border: 1px solid #000; font-size: 9pt; font-weight: bold;">${valor === 5 ? 'X' : ''}</td>
|
||||
<td style="text-align:center; border: 1px solid #000; font-size: 9pt; font-weight: bold;">${valor === 4 ? 'X' : ''}</td>
|
||||
<td style="text-align:center; border: 1px solid #000; font-size: 9pt; font-weight: bold;">${valor === 3 ? 'X' : ''}</td>
|
||||
<td style="text-align:center; border: 1px solid #000; font-size: 9pt; font-weight: bold;">${valor === 2 ? 'X' : ''}</td>
|
||||
<td style="text-align:center; border: 1px solid #000; font-size: 9pt; font-weight: bold;">${valor === 1 ? 'X' : ''}</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
|
||||
const dataHoje = new Date().toLocaleDateString('pt-PT');
|
||||
// Adicionamos Date.now() para garantir que o nome é sempre único e o sistema não usa cache
|
||||
const timestamp = Date.now();
|
||||
|
||||
// Resolve o asset do Expo de forma nativa e sem queixas do TS
|
||||
const assetLogo = Asset.fromModule(require('../../assets/images/epvclogo.png'));
|
||||
await assetLogo.downloadAsync();
|
||||
const logoEscolaUri = assetLogo.localUri || assetLogo.uri;
|
||||
|
||||
const html = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="pt-PT">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
@page { size: A4; margin: 15mm; }
|
||||
body { font-family: 'Times New Roman', serif; font-size: 10pt; color: #000; }
|
||||
@page { size: A4; margin: 12mm 15mm 15mm 15mm; }
|
||||
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 98%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Arial', sans-serif;
|
||||
font-size: 9.5pt;
|
||||
color: #000;
|
||||
line-height: 1.25;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.conteudo-principal {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
.header-table td { border: none; padding: 2px; }
|
||||
.main-table th { border: 1px solid #000; padding: 5px; background: #fff; text-align: center; font-size: 9pt; }
|
||||
.info-row { margin: 15px 0; }
|
||||
.sig-table { margin-top: 50px; width: 100%; }
|
||||
.sig-table td { width: 50%; text-align: center; vertical-align: bottom; }
|
||||
.sig-line { border-top: 1px solid #000; width: 80%; margin: 0 auto; padding-top: 5px; }
|
||||
|
||||
.header-logos-table { width: 100%; margin-top: 0px; margin-bottom: 8px; }
|
||||
.header-logos-table td { border: none; vertical-align: middle; }
|
||||
|
||||
.logo-epvc {
|
||||
height: 48px;
|
||||
width: auto;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.logo-estagios { height: 62px; width: auto; object-fit: contain; margin-top: -5px; margin-bottom: -5px; }
|
||||
|
||||
.title-center { text-align: center; }
|
||||
.title-center h1 { margin: 0; font-size: 11pt; font-weight: bold; text-transform: uppercase; }
|
||||
.title-center h2 { margin: 1px 0; font-size: 8.5pt; font-weight: normal; }
|
||||
.title-center h3 { margin: 2px 0; font-size: 9.5pt; font-weight: bold; text-decoration: underline; }
|
||||
|
||||
.info-box { border: 1px solid #000; padding: 5px; margin: 8px 0; font-size: 9pt; }
|
||||
.info-box table td { border: none; padding: 1px 0; }
|
||||
|
||||
.main-table th {
|
||||
border: 1px solid #000;
|
||||
padding: 4px 2px;
|
||||
background: #f2f2f2;
|
||||
text-align: center;
|
||||
font-size: 7.5pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.caixa-obs {
|
||||
border: 1px solid #000;
|
||||
min-height: 25px;
|
||||
padding: 4px;
|
||||
margin-top: 1px;
|
||||
font-size: 8.5pt;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.sig-table { width: 100%; margin-top: 15px; }
|
||||
.sig-table td { width: 50%; text-align: center; vertical-align: bottom; font-size: 9pt; }
|
||||
.sig-line { border-top: 1px solid #000; width: 70%; margin: 0 auto; padding-top: 2px; }
|
||||
|
||||
.footer-logos-container {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.footer-logos-container img {
|
||||
width: 100%;
|
||||
max-height: 34px;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table class="header-table">
|
||||
<tr>
|
||||
<td style="text-align: left; font-family: monospace;">EPVC.FI.08/1</td>
|
||||
<td></td>
|
||||
<td style="text-align: right;">Aprovado: 01/09/2016</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3" style="text-align: center; padding: 20px 0;">
|
||||
<h2 style="margin: 0; font-size: 14pt;">Escola Profissional de Vila do Conde</h2>
|
||||
<h3 style="margin: 5px 0; font-size: 11pt; font-weight: normal;">CURSO PROFISSIONAL TÉCNICO/A DE INFORMÁTICA DE GESTÃO</h3>
|
||||
<h3 style="margin: 5px 0; font-size: 12pt; text-decoration: underline;">FICHA DE AVALIAÇÃO FINAL DO ESTÁGIO</h3>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="info-row">
|
||||
<strong>Estagiário:</strong> ${alunoNome} <strong>Ano Letivo:</strong> 2025/2026<br><br>
|
||||
<strong>Instituição:</strong> __________________________________________________________________________
|
||||
<div class="conteudo-principal">
|
||||
|
||||
<table class="header-logos-table">
|
||||
<tr>
|
||||
<td style="width: 22%; text-align: left;">
|
||||
${logoEscolaUri ? `<img src="${logoEscolaUri}" class="logo-epvc" />` : ''}
|
||||
</td>
|
||||
<td style="width: 56%;" class="title-center">
|
||||
<h1>Escola Profissional de Vila do Conde</h1>
|
||||
<h2>CURSO PROFISSIONAL TÉCNICO/A DE INFORMÁTICA DE GESTÃO</h2>
|
||||
<h3>FICHA DE AVALIAÇÃO FINAL DO ESTÁGIO</h3>
|
||||
</td>
|
||||
<td style="width: 22%; text-align: right;">
|
||||
${imgAppB64 ? `<img src="${imgAppB64}" class="logo-estagios" />` : ''}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="info-box">
|
||||
<table style="width:100%;">
|
||||
<tr>
|
||||
<td><strong>Estagiário:</strong> ${alunoNome}</td>
|
||||
<td style="text-align: right;"><strong>Ano Letivo:</strong> 2025/2026</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="padding-top: 3px;"><strong>Instituição:</strong> __________________________________________________________________________</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<table class="main-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 4%;">#</th>
|
||||
<th style="width: 56%; text-align: left; padding-left: 5px;">Parâmetros de Avaliação</th>
|
||||
<th style="width: 8%;">Excelente<br>(5)</th>
|
||||
<th style="width: 8%;">Muito Bom<br>(4)</th>
|
||||
<th style="width: 8%;">Bom<br>(3)</th>
|
||||
<th style="width: 8%;">Médio<br>(2)</th>
|
||||
<th style="width: 8%;">Insuficiente<br>(1)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${linhasTabelaHtml}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p style="text-align: justify; margin: 8px 0 4px 0; font-size: 9pt;">
|
||||
Pelas competências demonstradas durante o estágio de Formação em Contexto de Trabalho, propomos que seja atribuída ao estagiário a classificação de <strong style="text-decoration: underline;"> ${notaFinal} </strong> valores.
|
||||
</p>
|
||||
|
||||
<p style="margin: 3px 0 1px 0; font-weight: bold;">Observações:</p>
|
||||
<div class="caixa-obs">
|
||||
${observacoes.trim() ? observacoes.replace(/\n/g, '<br>') : 'Nenhum comentário adicional registado.'}
|
||||
</div>
|
||||
|
||||
<p style="margin: 6px 0 0 0; text-align: right; font-size: 9pt; font-style: italic;">
|
||||
Vila do Conde, ${dataHoje}
|
||||
</p>
|
||||
|
||||
<table class="sig-table">
|
||||
<tr>
|
||||
<td>
|
||||
<div style="height: 20px;"></div>
|
||||
<div class="sig-line">O Formador acompanhante</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="height: 20px;"></div>
|
||||
<div class="sig-line">O Monitor de estágio</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<table class="main-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5%;">#</th>
|
||||
<th style="width: 55%;">Parâmetros de Avaliação</th>
|
||||
<th style="width: 8%;">5</th>
|
||||
<th style="width: 8%;">4</th>
|
||||
<th style="width: 8%;">3</th>
|
||||
<th style="width: 8%;">2</th>
|
||||
<th style="width: 8%;">1</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${linhasTabelaHtml}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="footer-logos-container">
|
||||
${imgFundoB64 ? `<img src="${imgFundoB64}" />` : ''}
|
||||
</div>
|
||||
|
||||
<p style="text-align: justify; margin-top: 20px;">
|
||||
Pelas competências demonstradas durante o estágio de Formação em Contexto de Trabalho, propomos que seja atribuída ao estagiário a classificação de <strong>${notaFinal}</strong> valores.
|
||||
</p>
|
||||
|
||||
<p><strong>Observações:</strong></p>
|
||||
<div style="border: 1px solid #000; min-height: 40px; padding: 5px;">${observacoes}</div>
|
||||
|
||||
<p style="margin-top: 30px; text-align: right;">
|
||||
Escola Profissional de Vila do Conde, ${dataHoje}
|
||||
</p>
|
||||
|
||||
<table class="sig-table">
|
||||
<tr>
|
||||
<td><div class="sig-line">O Formador acompanhante</div></td>
|
||||
<td><div class="sig-line">O Monitor de estágio</div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
const { uri } = await Print.printToFileAsync({ html });
|
||||
|
||||
// O truque está aqui: incluímos o timestamp no nome do ficheiro final
|
||||
const safeName = alunoNome.replace(/\s/g, '_');
|
||||
const finalPath = `${FileSystem.documentDirectory}Avaliacao_${safeName}_${timestamp}.pdf`;
|
||||
const safeName = alunoNome.replace(/[^a-zA-Z0-9]/g, '_');
|
||||
const finalPath = `${FileSystem.documentDirectory}Ficha_Avaliacao_${safeName}_${timestamp}.pdf`;
|
||||
|
||||
await FileSystem.moveAsync({ from: uri, to: finalPath });
|
||||
await Sharing.shareAsync(finalPath);
|
||||
await Sharing.shareAsync(finalPath, { mimeType: 'application/pdf', UTI: 'com.adobe.pdf' });
|
||||
|
||||
} catch (e) {
|
||||
Alert.alert('Erro', 'Falha ao gerar o documento.');
|
||||
Alert.alert('Erro', 'Não foi possível compilar o documento.');
|
||||
} finally {
|
||||
setGerandoPDF(false);
|
||||
}
|
||||
|
||||
BIN
assets/images/epvclogo.png
Normal file
BIN
assets/images/epvclogo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 181 KiB |
Reference in New Issue
Block a user