Obieg dokumentów odgrywa ważną rolę w procesie tworzenia systemu korporacyjnego. Format fp3 jest głównym dokumentem gotowego raportu, jeżeli korzystasz z FastReport VCL w swoim systemie.
Aby ułatwić generowanie dokumentów różnych typów z formatu wewnętrznego bez konieczności przebudowywania raportów, poszerzyliśm nasze komponenty klient-serwer, które teraz umożliwiają przyjmowanie formatu fp3 od klientów i konwertowanie go do dowolnego dostępnego formatu eksportu.
Dodatkowo wprowadzono system buforowania, przy pomocy którego serwer może odmówić przyjęcia pliku i pracować z pamięcią podręczną. Istnieją również ograniczenia, na przykład maksymalny rozmiar odbieranego pliku.
Aby Twój serwer mógł odbierać i przetwarzać pliki fp3, musisz dodać kilka ustawień do pliku config (plik xml z ustawieniami).
HeaderMaxSize - maksymalny rozmiar nagłówka HTTP w bajtach. Maksymalna wartość to 16384.
ContentMaxSize - maksymalny rozmiar przesyłanych plików fp3 w megabajtach (0 - brak limitu).
Zaktualizowaliśmy również nasze wersje demonstracyjne projektów, które można pobrać tutaj.
Od strony klienta będziemy analizować skrypt php w roli klienta, ale oczywiście klient może być napisany w dowolnym języku programowania.
Formularz HTML dla skryptu:
<html> <head> <meta charset="utf-8"> </head> <body> <form enctype="multipart/form-data" action="post.php" method="POST"> <!-- MAX_FILE_SIZE musi być określone przed wczytaniem pliku pole ---> <input type="hidden" name="MAX_FILE_SIZE" value="3000000000" /> <!-- Nazwa elementu wejściowego definiuje nazwę w tablicy $_FILES --> Send this: <input name="userfile" type="file" /> <input type="submit" value="Send File" /> </form> </body> </html>
Post.php:
<?php // Adres serwera FastReport $host ='http://localhost:8097'; // Format eksportu $exportFormat = 'PDF'; // Nazwa pliku wybranego przez użytkownika $OldName = $_FILES['userfile']['name']; // Faktyczna nazwa po pobraniu (zamień rozszerzenie tmp na fp3) $name = substr_replace($_FILES['userfile']['tmp_name'], 'fp3', -3); // Zapisz na serwerze php move_uploaded_file($_FILES['userfile']['tmp_name'], $name); // Otwórz $file = new \CURLFile($name); // Zainicjuj sesję cURL $ch = curl_init(); // Zainstaluj adres url do pobrania curl_setopt($ch, CURLOPT_URL, $host); // Wybierz metodę zapytania (Post) curl_setopt($ch, CURLOPT_POST, true); // Aby odczytać otrzymane dane curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Aby odczytać nagłówek zwrotny curl_setopt($ch, CURLOPT_HEADER, 1); // W przypadku dużych plików należy zwiększyć czas oczekiwania na wysłanie (domyślnie 30 sekund), ustawiony na 0, oznacza czekanie do skutku. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); // Generowanie MD5 dla pliku. $md5 = md5_file($name); // Format wysyłania i MD5 curl_setopt($ch, CURLOPT_HTTPHEADER , array('Format-Export: '.$exportFormat, 'Content-MD5: '.$md5)); // Kompresuj plik przed wysłaniem $data = array($exportFormat => $file); // Wysyłanie pliku curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // Oczekiwanie na odpowiedź $response = curl_exec($ch); // Debugowanie zwrotnego check-outu if (empty($response)) { echo 'received an empty response'; } else { if (strstr($response, 'HTTP/1.1 301') == '') { // Coś poszło nie tak. Serwer wysłał nieoczekiwaną odpowiedź echo '404'; curl_close($ch); exit; } if (curl_errno($ch)) { // Serwer wyświetlił błąd, który jest zaznaczony na czerwono echo '<span style="color:red">'; echo 'error: '.curl_error($ch); echo '</span>'; } else { // Uzyskaj adres z odpowiedzi serwera FastReport który ma być używany do otrzymywania wyników eksportu $Location = GetLocationFromHeader($response); if (empty($Location)) { echo 'error: Location not found'; } else { //Możesz skierować klienta na adres do odbioru pliku, ale nie w przypadku gdy serwer FastReport jest podłączony lokalnie do serwera php i nie ma dostępu do Internetu. Całość będziesz musiał pobrać za pomocą serwera php i jest to bezpieczniejsze z punktu widzenia logiki, aby zabezpieczyć dokumenty użytkowników. $file = file_get_contents_curl($host.$Location); if (empty($file)) { echo 'error: file missing'; } { // Aby plik został zwrócony do klienta, musimy wygenerować nową nazwę. // Procedura jest realizowana w następujący sposób: Nazwa pliku jest taka sama jak nazwa klienta, a wynik z odpowiedzi serwera jest analizowany w celu uzyskania rozszerzenia. // Wyodrębnijmy format z odpowiedzi. Weźmy starą nazwę, którą wysłał nam klient, i zamieńmy rozszerzenie na wynik eksportu (jeśli klient wysłał 123.fp3, otrzymamy 123.pdf). $Format = getExtension(GetFileNameFromLocation($Location)); $OldName = substr_replace($OldName, $Format, -3); // Przesyłanie plików z serwera php do klienta header('X-Accel-Redirect: storage/'.$OldName); header('Content-Disposition: attachment; filename="'.$OldName.'"'); echo $file; } } } } curl_close($ch); // Funkcje dodatkowe // Pozyskuje adres z odpowiedzi serwera, aby uzyskać wynik konwersji. function GetLocationFromHeader($arg_1) { $Location = strstr($arg_1, 'Location'); $Location = strstr($Location, '/'); $Location = substr($Location, 0, strrpos($Location, 'SessionId')-2); return $Location; } // Pobieranie nazwy pliku z odpowiedzi function GetFileNameFromLocation($arg_1) { $FN = substr($arg_1, strripos($arg_1, '/')+1, strlen($arg_1)); return $FN; } // Pobieranie rozszerzenia z nazwy pliku function getExtension($fileName) { return substr($fileName, strrpos($fileName, '.') + 1); } // Szybszy odpowiednik funkcji 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; } ?>
Takie rozwiązanie pozwala pozbyć się kilku poważnych problemów. Nie trzeba będzie przebudowywać raportów, co zmniejsza obciążenie serwera. Raporty można przechowywać w dowolnym, dogodnym miejscu, a stronę kliencką można napisać w dowolnym, wygodnym dla użytkownika języku programowania.