Para a construção de um sistema corporativo, o gerenciamento de documentos desempenha um papel importante. Se o seu sistema usa FastReport VCL, o documento principal do relatório final é o formato fp3.
Para facilitar a geração de diferentes tipos de documentos a partir do formato interno sem reconstruir os relatórios, expandimos nossos componentes cliente-servidor, que agora permitem aceitar o formato fp3 dos clientes e convertê-lo em qualquer formato de exportação disponível.
Isso é acompanhado por um sistema de cache, onde o servidor pode se recusar a aceitar um arquivo que já possui e trabalhar com o Cache. Também estão incluídas pequenas configurações, como o tamanho máximo do arquivo recebido.
Para que seu servidor possa aceitar e processar arquivos fp3, você precisa adicionar algumas configurações à configuração (arquivo xml com configurações).
HeaderMaxSize é o tamanho máximo do cabeçalho HTTP em bytes. O valor máximo é 16384.
ContentMaxSize é o tamanho máximo de download de arquivos fp3 em megabytes (0 - sem restrições).
Também atualizamos nossos projetos de demonstração que você pode baixar aqui.
Para a parte do cliente, analisaremos o script php como cliente, mas é claro que o cliente pode ser escrito condicionalmente em qualquer linguagem de programação.
Formulário HTML para o script:
<html> <head> <meta charset="utf-8"> </head> <body> <form enctype="multipart/form-data" action="post.php" method="POST"> <!-- O campo MAX_FILE_SIZE deve ser especificado antes do campo de Upload de arquivo --> <input type="hidden" name="MAX_FILE_SIZE" value="3000000000" /> <!-- O nome do elemento input define o nome na matriz $_FILES --> Send this: <input name="userfile" type="file" /> <input type="submit" value="Send File" /> </form> </body> </html>
Post.php:
<?php //Endereço do servidor FastReport $host ='http://localhost:8097'; //Formato da exportação $exportFormat = 'PDF'; //Nome do arquivo que o usuário selecionou $OldName = $_FILES['userfile']['name']; //O nome real desse após o nosso download (substitua a extensão tmp por fp3) $name = substr_replace($_FILES['userfile']['tmp_name'], 'fp3', -3); //Salvamos no servidor php move_uploaded_file($_FILES['userfile']['tmp_name'], $name); //Abrimos $file = new \CURLFile($name); //Inicializamos uma sessão com cURL $ch = curl_init(); //Definimos URL para download curl_setopt($ch, CURLOPT_URL, $host); //Escolha um método de solicitação (Post) curl_setopt($ch, CURLOPT_POST, true); //Para ler os dados retornados curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //Para ler o cabeçalho retornado curl_setopt($ch, CURLOPT_HEADER, 1); //Para arquivos grandes, é necessário aumentar a espera pelo envio (por padrão, 30 segundos), está definido como 0, o que significa espera infinita. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); //Gerar MD5 para um arquivo. $md5 = md5_file($name); //Envio de formato e MD5 curl_setopt($ch, CURLOPT_HTTPHEADER , array('Format-Export: '.$exportFormat, 'Content-MD5: '.$md5)); //Empacotando o arquivo antes do envio $data = array($exportFormat => $file); //Enviando um arquivo curl_setopt($ch, CURLOPT_POSTFIELDS, $data); //Aguardando uma resposta $response = curl_exec($ch); //Verificação de retorno de depuração if (empty($response)) { echo 'received an empty response'; } else { if (strstr($response, 'HTTP/1.1 301') == '') { //Algo deu errado. O servidor retornou uma resposta inesperada echo '404'; curl_close($ch); exit; } if (curl_errno($ch)) { //O servidor retornou um erro que exibimos em vermelho echo '<span style="color:red">'; echo 'error: '.curl_error($ch); echo '</span>'; } else { //Extraímos o endereço da resposta do servidor FastReport para obter os resultados da exportação $Location = GetLocationFromHeader($response); if (empty($Location)) { echo 'error: Location not found'; } else { //Pode-se direcionar o cliente para o endereço para obter o arquivo, mas não em uma arquitetura em que o servidor FastReport esteja conectado ao servidor php localmente e não tenha acesso à Internet. Terá que baixar tudo usando o servidor php e é mais seguro do ponto de vista da lógica para impedir o acesso aos documentos de outras pessoas. $file = file_get_contents_curl($host.$Location); if (empty($file)) { echo 'error: file missing'; } { //Precisamos gerar um novo nome para enviar o arquivo para o cliente. //Tudo é implementado da seguinte maneira: o nome do arquivo é o mesmo que o cliente e a resposta do servidor é analisada para obter a extensão. //Extraia o formato da resposta. Pegamos o nome antigo que o cliente nos enviou e substituímos a extensão pelo resultado da exportação (se ele enviou 123.fp3, em seguida, obter 123.pdf). $Format = getExtension(GetFileNameFromLocation($Location)); $OldName = substr_replace($OldName, $Format, -3); //Transferir arquivos do servidor php para o cliente header('X-Accel-Redirect: storage/'.$OldName); header('Content-Disposition: attachment; filename="'.$OldName.'"'); echo $file; } } } } curl_close($ch); //Funções auxiliares //Recupera o endereço da resposta do servidor para obter o resultado da conversão function GetLocationFromHeader($arg_1) { $Location = strstr($arg_1, 'Location'); $Location = strstr($Location, '/'); $Location = substr($Location, 0, strrpos($Location, 'SessionId')-2); return $Location; } //Obtendo o nome do arquivo da resposta function GetFileNameFromLocation($arg_1) { $FN = substr($arg_1, strripos($arg_1, '/')+1, strlen($arg_1)); return $FN; } //Obtendo uma extensão de um nome de arquivo function getExtension($fileName) { return substr($fileName, strrpos($fileName, '.') + 1); } //Análogo mais rápido da função file_get_contents function file_get_contents_curl($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); $data = curl_exec($ch); curl_close($ch); return $data; } ?>
Dessa forma, você poderá se livrar de alguns grandes problemas. Não será necessário reconstruir os relatórios, o que reduz a carga no servidor. Os relatórios podem ser armazenados em qualquer lugar conveniente para você e escrever a parte do cliente em uma linguagem de programação confortável para você.