versao word 5
This commit is contained in:
parent
716bb2a115
commit
72e5e3b59c
198
export_html.php
198
export_html.php
@ -1,5 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
// export_html.php
|
// export_html.php - Geração de Documento Word XML (WordprocessingML) v3
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
|
||||||
// 1. Validar e obter o ID
|
// 1. Validar e obter o ID
|
||||||
if (!isset($_GET['id']) || !filter_var($_GET['id'], FILTER_VALIDATE_INT)) {
|
if (!isset($_GET['id']) || !filter_var($_GET['id'], FILTER_VALIDATE_INT)) {
|
||||||
@ -12,7 +16,6 @@ require_once __DIR__ . '/db/config.php';
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
|
|
||||||
// 3. Buscar dados da instalação
|
// 3. Buscar dados da instalação
|
||||||
$stmt = $pdo->prepare("SELECT * FROM installations WHERE id = :id");
|
$stmt = $pdo->prepare("SELECT * FROM installations WHERE id = :id");
|
||||||
$stmt->bindParam(':id', $installation_id, PDO::PARAM_INT);
|
$stmt->bindParam(':id', $installation_id, PDO::PARAM_INT);
|
||||||
@ -30,107 +33,126 @@ try {
|
|||||||
$images = $img_stmt->fetchAll(PDO::FETCH_ASSOC);
|
$images = $img_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
die("Erro ao acessar o banco de dados: " . $e->getMessage());
|
// Em caso de erro, envie um cabeçalho de erro e uma mensagem clara.
|
||||||
|
header("HTTP/1.1 500 Internal Server Error");
|
||||||
|
die("Erro no servidor: Não foi possível conectar ao banco de dados. Detalhe: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Início da Geração MHTML ---
|
// --- Funções Auxiliares ---
|
||||||
|
function xml_escape($string) {
|
||||||
|
return htmlspecialchars($string, ENT_XML1, 'UTF-8');
|
||||||
|
}
|
||||||
|
|
||||||
$boundary = "----=" . md5(uniqid(time()));
|
// --- Preparar variáveis ---
|
||||||
$filename = "instalacao_" . $installation['id'] . "_" . str_replace(' ', '_', $installation['client_name']) . ".doc";
|
$filename = "instalacao_" . $installation['id'] . ".doc";
|
||||||
|
|
||||||
// Cabeçalhos principais para MHTML
|
// --- Geração do XML ---
|
||||||
header("Content-Type: multipart/related; boundary=\"$boundary\"");
|
|
||||||
header("Content-Disposition: attachment; filename=\"" . $filename . "\"");
|
|
||||||
|
|
||||||
// Parte 1: Conteúdo HTML
|
$xml_template = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
$html_content = <<<HTML
|
<?mso-application progid="Word.Document"?>
|
||||||
<!DOCTYPE html>
|
<w:wordDocument
|
||||||
<html lang="pt-BR">
|
xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
|
||||||
<head>
|
xmlns:v="urn:schemas-microsoft-com:vml"
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||||
<title>Relatório de Instalação - {htmlspecialchars($installation['client_name'])}</title>
|
xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint"
|
||||||
<style>
|
xmlns:aml="http://schemas.microsoft.com/aml/2001/core"
|
||||||
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
|
xmlns:w10="urn:schemas-microsoft-com:office:word"
|
||||||
.container { width: 90%; margin: 0 auto; }
|
xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage">
|
||||||
h1 { color: #0056b3; border-bottom: 2px solid #f0f0f0; padding-bottom: 10px; }
|
|
||||||
.details-table { width: 100%; border-collapse: collapse; margin-bottom: 20px; }
|
|
||||||
.details-table td { padding: 8px; border: 1px solid #ddd; }
|
|
||||||
.details-table td:first-child { font-weight: bold; background-color: #f9f9f9; width: 25%; }
|
|
||||||
.images-section img { max-width: 400px; margin: 10px; border: 1px solid #ccc; padding: 5px; }
|
|
||||||
.section-title { font-size: 1.5em; color: #0056b3; margin-top: 20px; margin-bottom: 10px; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<h1>Relatório de Instalação</h1>
|
|
||||||
<h2 class="section-title">Detalhes do Cliente e Instalação</h2>
|
|
||||||
<table class="details-table">
|
|
||||||
<tr><td>ID da Instalação</td><td>{htmlspecialchars($installation['id'])}</td></tr>
|
|
||||||
<tr><td>Cliente</td><td>{htmlspecialchars($installation['client_name'])}</td></tr>
|
|
||||||
<tr><td>Endereço</td><td>{htmlspecialchars($installation['address'])}</td></tr>
|
|
||||||
<tr><td>Técnico Responsável</td><td>{htmlspecialchars($installation['technician_name'])}</td></tr>
|
|
||||||
<tr><td>Data</td><td>{date("d/m/Y H:i", strtotime($installation['created_at']))}</td></tr>
|
|
||||||
<tr><td>Status</td><td>{ucfirst(htmlspecialchars($installation['status']))}</td></tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h2 class="section-title">Dados Elétricos</h2>
|
<w:body>
|
||||||
<table class="details-table">
|
%s
|
||||||
<tr><td>Tensão (V)</td><td>{htmlspecialchars($installation['voltage'] ?? 'N/A')}</td></tr>
|
</w:body>
|
||||||
<tr><td>Fase-Neutro-Terra</td><td>{htmlspecialchars($installation['phase_neutral_ground'] ?? 'N/A')}</td></tr>
|
</w:wordDocument>';
|
||||||
<tr><td>Saída do Disjuntor</td><td>{htmlspecialchars($installation['breaker_output'] ?? 'N/A')}</td></tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h2 class="section-title">Observações</h2>
|
$xml_content = '';
|
||||||
<p>{nl2br(htmlspecialchars($installation['observations'] ?? 'Nenhuma observação.'))}</p>
|
|
||||||
HTML;
|
|
||||||
|
|
||||||
// Preparar a seção de imagens
|
// Título
|
||||||
$images_html = '';
|
$xml_content .= '<w:p><w:r><w:rPr><w:b/><w:sz w:val="32"/></w:rPr><w:t>Relatório de Instalação</w:t></w:r></w:p><w:p/>';
|
||||||
$image_parts = '';
|
|
||||||
|
|
||||||
|
// Função para criar linhas da tabela
|
||||||
|
function create_table_rows($data) {
|
||||||
|
$rows = '';
|
||||||
|
foreach ($data as $label => $value) {
|
||||||
|
$label = xml_escape($label);
|
||||||
|
$value = xml_escape($value);
|
||||||
|
$rows .= <<<XML
|
||||||
|
<w:tr>
|
||||||
|
<w:tc><w:p><w:r><w:rPr><w:b/></w:rPr><w:t>{$label}</w:t></w:r></w:p></w:tc>
|
||||||
|
<w:tc><w:p><w:r><w:t>{$value}</w:t></w:r></w:p></w:tc>
|
||||||
|
</w:tr>
|
||||||
|
XML;
|
||||||
|
}
|
||||||
|
return $rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tabela de Informações
|
||||||
|
$info_data = [
|
||||||
|
"ID da Instalação" => $installation['id'],
|
||||||
|
"Cliente" => $installation['client_name'],
|
||||||
|
"Endereço" => $installation['address'],
|
||||||
|
"Técnico" => $installation['technician_name'],
|
||||||
|
"Data" => date("d/m/Y H:i", strtotime($installation['created_at'])),
|
||||||
|
"Status" => ucfirst($installation['status'])
|
||||||
|
];
|
||||||
|
$xml_content .= '<w:tbl><w:tblPr><w:tblW w:w="10000" w:type="pct"/></w:tblPr>' . create_table_rows($info_data) . '</w:tbl><w:p/>';
|
||||||
|
|
||||||
|
// Tabela de Dados Elétricos
|
||||||
|
$electric_data = [
|
||||||
|
"Tensão (V)" => $installation['voltage'] ?? 'N/A',
|
||||||
|
"Fase-Neutro-Terra" => $installation['phase_neutral_ground'] ?? 'N/A',
|
||||||
|
"Saída do Disjuntor" => $installation['breaker_output'] ?? 'N/A'
|
||||||
|
];
|
||||||
|
$xml_content .= '<w:p><w:r><w:rPr><w:b/><w:sz w:val="28"/></w:rPr><w:t>Dados Elétricos</w:t></w:r></w:p>';
|
||||||
|
$xml_content .= '<w:tbl><w:tblPr><w:tblW w:w="10000" w:type="pct"/></w:tblPr>' . create_table_rows($electric_data) . '</w:tbl><w:p/>';
|
||||||
|
|
||||||
|
// Observações
|
||||||
|
$observations = xml_escape($installation['observations'] ?? 'Nenhuma observação.');
|
||||||
|
$xml_content .= '<w:p><w:r><w:rPr><w:b/><w:sz w:val="28"/></w:rPr><w:t>Observações</w:t></w:r></w:p>';
|
||||||
|
$xml_content .= "<w:p><w:r><w:t>{\$observations}</w:t></w:r></w:p>";
|
||||||
|
|
||||||
|
// Imagens
|
||||||
if (!empty($images)) {
|
if (!empty($images)) {
|
||||||
$images_html = '<h2 class="section-title">Imagens da Instalação</h2><div class="images-section" style="page-break-before: always;">';
|
$xml_content .= '<w:p><w:r><w:br w:type="page"/></w:r></w:p>';
|
||||||
|
$xml_content .= '<w:p><w:r><w:rPr><w:b/><w:sz w:val="28"/></w:rPr><w:t>Imagens da Instalação</w:t></w:r></w:p>';
|
||||||
|
|
||||||
foreach ($images as $i => $image) {
|
foreach ($images as $image) {
|
||||||
$image_full_path = realpath(__DIR__ . '/' . $image['image_path']);
|
$image_path = __DIR__ . '/' . $image['image_path'];
|
||||||
|
if (file_exists($image_path)) {
|
||||||
|
$image_data = base64_encode(file_get_contents($image_path));
|
||||||
|
list($width_px, $height_px) = getimagesize($image_path);
|
||||||
|
|
||||||
if (file_exists($image_full_path)) {
|
$width_pt = $width_px * 0.75; // Convert pixels to points
|
||||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
$height_pt = $height_px * 0.75;
|
||||||
$image_mime = finfo_file($finfo, $image_full_path);
|
|
||||||
finfo_close($finfo);
|
|
||||||
|
|
||||||
$image_data = base64_encode(file_get_contents($image_full_path));
|
$max_width_pt = 450; // Largura máxima de aprox. 6 polegadas
|
||||||
$cid = "image" . $i . "@" . md5($image['image_path']);
|
if ($width_pt > $max_width_pt) {
|
||||||
|
$ratio = $max_width_pt / $width_pt;
|
||||||
// Adiciona a tag <img> ao HTML
|
$width_pt = $max_width_pt;
|
||||||
$images_html .= '<img src="cid:' . $cid . '" alt="Imagem da Instalação ' . ($i+1) . '"><br>';
|
$height_pt = $height_pt * $ratio;
|
||||||
|
|
||||||
// Cria a parte MIME para a imagem
|
|
||||||
$image_parts .= "--$boundary\r\n";
|
|
||||||
$image_parts .= "Content-Type: $image_mime\r\n";
|
|
||||||
$image_parts .= "Content-Transfer-Encoding: base64\r\n";
|
|
||||||
$image_parts .= "Content-ID: <$cid>\r\n";
|
|
||||||
$image_parts .= "Content-Location: " . basename($image['image_path']) . "\r\n\r\n";
|
|
||||||
$image_parts .= chunk_split($image_data) . "\r\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$images_html .= '</div>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finaliza o HTML
|
$shape_id = '_x0000_i' . substr(uniqid(), 5);
|
||||||
$html_content .= $images_html;
|
$image_rid = 'rId' . substr(uniqid(), 5);
|
||||||
$html_content .= '</div></body></html>';
|
|
||||||
|
|
||||||
// Monta a saída final
|
$xml_content .= '
|
||||||
echo "--$boundary\r\n";
|
<w:p>
|
||||||
echo "Content-Type: text/html; charset=\"UTF-8\"\r\n";
|
<w:r>
|
||||||
echo "Content-Transfer-Encoding: 7bit\r\n\r\n";
|
<w:pict>
|
||||||
echo $html_content . "\r\n";
|
<w:binData w:name="wordml://' . $image_rid . '.jpg">' . $image_data . '</w:binData>
|
||||||
|
<v:shape id="' . $shape_id . '" type="#_x0000_t75" style="width:' . round($width_pt) . 'pt;height:' . round($height_pt) . 'pt">
|
||||||
// Adiciona as partes das imagens
|
<v:imagedata src="wordml://' . $image_rid . '.jpg" o:title="image"/>
|
||||||
echo $image_parts;
|
</v:shape>
|
||||||
|
</w:pict>
|
||||||
// Fecha o boundary final
|
</w:r>
|
||||||
echo "--$boundary--\r\n";
|
</w:p>
|
||||||
|
<w:p/>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Enviar para o navegador ---
|
||||||
|
header("Content-Type: application/vnd.ms-word; charset=UTF-8");
|
||||||
|
header("Content-Disposition: attachment; filename=\"" . $filename . "\"");
|
||||||
|
echo sprintf($xml_template, $xml_content);
|
||||||
|
ob_end_flush();
|
||||||
?>
|
?>
|
||||||
Loading…
x
Reference in New Issue
Block a user