[PHP/JS]Vytvoření PDF souboru s výběrem kódu ze stránek

Webdesign, HTML, CSS, Flash, PHP, ASP, .NET, JavaScript. Kritika www stránek na Smetišti.

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod Václav M. 25. 1. 2022 18:57

Pro jeden ze svých testovacích projektů jsem se rozhodl, že kus kódu použiju jako obsah PDF souboru. A to tak, že AJAxem pošlu vybraný kus kódu ke zpracování na PDF.

Jenže se mi vyskytl problém: jQuery funkce html mi nějak nechce fungovat. S největší pravděpodobností je použitá na špatný výběr.

Přibližná struktura kódu je takováto:
Kód: Vybrat vše
<table>
<tr>
<td>(tlačítko)</td>
<td>(výsledek funkce tlačítka)</td>
</tr>
</table>

Výsledkem skriptu spuštěného tlačítkem z první sloupce je tabulka - vložená do druhého sloupce. Zároveň s výsledkem v podobě takovéto tabulky
Kód: Vybrat vše
<table>
...
<tr>
<td>(datum)</td>
<td>(číslo)</td>
</tr>
...
</table>

se sloupci přiřadí atribut onclick spouštějící skript, jenž má předat jeho obsah (tedy tuto vytvořenou tabulku) ke zpracování.

Výsledná podoba první tabulky je takováto:
Kód: Vybrat vše
<table>
<tr>
<td>(tlačítko)</td>
<td onclick="VytvoritPDFRozpis()">(výsledek funkce tlačítka)</td>
</tr>
</table>

Skript pro spuštění vyvoření PDF souboru je takovýto
Kód: Vybrat vše
function VytvoritPDFRozpisu()
{
   $.ajax({
      type: 'POST',
      url: '_VytvoreniPDFRozpisu.php',
      data: {
         Content: $(this).html()
      },
      async: true,
      success: function (PDF)
      {
         alert(PDF);
      },
      error: function ()
      {
         alert('Chyba');
      }
   });
}

V tomto stavu je Content bez obsahu. Když funkci html nahradím funkcí siblings, tak mi ale pošle úplně všechno - ne jen požadovaný výběr.
Václav M.
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 25. 1. 2022 19:08

Posíláš obsah elementu "td" kde jsi klikl. Je to záměr? Co vrátí výpis do konzole "$(this).html()"?
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod Václav M. 25. 1. 2022 19:40

Just_jo píše:Posíláš obsah elementu "td" kde jsi klikl.
Je to záměr?

Ano - je to záměr.

Co vrátí výpis do konzole "$(this).html()"?

AJAX, resp. PHP soubor, kde je teď aktivní pouze
Kód: Vybrat vše
echo $_POST['Content'];

mi vrátí tohle:
Kód: Vybrat vše
<b>Notice</b>:  Undefined index: Content in <b>A:\WWW\Kilometrovnik\_VytvoreniPDFRozpisu.php</b> on line <b>7</b>
Václav M.
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 25. 1. 2022 21:57

Prosím o výpis z konzole JS - před ajax hoď console.write($(this)); případně i s html()

Taky možná budeš potřebovat serialize
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod Václav M. 25. 1. 2022 22:26

console.write mi hlásí jako nesmysl - ale console.log mi hlásí následující:

s $(this): Object {0: window, length: 1}

s $(this).html(): undefined
Václav M.
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 26. 1. 2022 16:18

Se omlouvám za špatnou syntaxi - míchání jazyků.

No vypadá to, že máš špatný objekt.
Zkus toto
https://stackoverflow.com/questions/155 ... ing-object
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod Václav M. 26. 1. 2022 17:10

Díky.

zvenku this do argumentu funkce - a event dovnitř místo this.
Václav M.
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 26. 1. 2022 17:38

Ten "event" je volitelný - já bych třeba volil jen "e", ale je to skoro jedno.
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod Václav M. 26. 1. 2022 20:10

Já ty zkratky používám nerad.
:arrow:

Hmm, ale když už jsem vyřešil jeden problém, objevil se další. A ten má název TCPDF/FPDF.

No, jsou to vlastně dva různé projekty pro generování PDF souborů z PHP, ale oba mají několik věcí společných.

1) Chybí jim jakákoliv smysluplná dokumentace.
2) A ani jeden nepoužívá ani základní konvenci všude stejně*

A FPDF ještě k tomu používá opravdu hodně šílené konstrukce, které odkazují na PHP4.

A z chybových hlášení TCPDF člověk nepochopí vůbec nic.

* Omlouvám se, ale tak jsem si to doporučení přeložil já. Protože jde o to, že by všechny vlastnnosti, funkce/metody atd. měly mít v celém rozsahu jednotný tvar (ať už byl zvolen jakýkoliv). A tohle přiznávám i přes to, že já na konvence kašlu. Resp. tato výše uvedená je ta jediná, kterou opravdu dodržuji.
:?:
A zvolené TCPDF mi hlásí, že nemůže soubor zvoleného názvu vytvořit. A já tedy naprosto nechápu proč.

Kód: Vybrat vše
<b>Warning</b>:
fopen(file://localhost/kilometrovnik/PDF/MedianKilometruZaJizduDleMesice.pdf):
failed to open stream:
No such file or directory in
<b>A:\WWW\Kilometrovnik\TCPDF\include\tcpdf_static.php</b> on line <b>1842</b>
<br />
<strong>TCPDF ERROR:
</strong>Unable to create output file: localhost/kilometrovnik/PDF/MedianKilometruZaJizduDleMesice.pdf


Jediné, co mě napadá je, že se mu nelíbí adresa vytvářeného souboru. Ale nevím, jak jí upravit tak, aby byla OK.
Václav M.
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 26. 1. 2022 22:15

Na jednom projektu se používal TCPDF - asi bude problém v cestě k souboru. Nešlo by to s relativní cestou? Případně využít __FILE__ k získání rootu absolutní cesty?
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod Václav M. 26. 1. 2022 23:45

Tak jsem zkusil "absolutní" cestu do složky projektu (jako kdybych to ukládal normálně do počítače) - a ta fungovala, ale je to pěkná čuňárna, která je odpustitelná jen tím, že:

1) to neopustí můj počítač
2) účelem

Akorát, že jsem chtěl, aby to uložil jako na server. Proto ta adresa s localhostem. Ale asi to jinak nejde než s
Kód: Vybrat vše
$file_name = dirname(__FILE__) . '/PDF/' . $_POST['ID'];
$file_name .= ".pdf";

kdy v druhém řádku by do názvu souboru mělo být přidáno datum vytvoření (spíše pro jistotu).
Václav M.
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 27. 1. 2022 16:29

Lze to udělat i s relativní cestou, jen netuším kam by to ukládalo.

Ochranu přípony lze použít z https://www.php.net/manual/en/function.pathinfo.php
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod Václav M. 27. 1. 2022 19:40

Hmm, díky. Ale já to tedy raději nechám tak, jak to je. ;-) Jen si nejsem jistý, zda by to mohlo fungovat v ostrém provozu (a obzvláště na sdílených serverech jako endora apod.)

:arrow:

Co ale stále uniká řešení je obsah pro PDF soubor. Bohužel, prosté zkopírování obsahu prostě nemá ten správný výsledek, který by se mi líbil. Ona totiž podpora TCPDF pro import HTML obsahu je dost omezená.

Nově tedy místo toho raději vyextrahuji ty žádané informace a podobu jim dám až v tom PDF souboru. Což je vlastně řešení, o kterém jsem uvažoval původně. Jenže to vypadá, že jQuery si neví rady s selektorem ve tvaru
Kód: Vybrat vše
table[śummary="text"] > tr


Když dám console.log na proměnnou, která tento selektor nese, tak jej vypíše - ale když jej použiju do
Kód: Vybrat vše
$(Vyber).each(function ()
{
   console.log(Vyber);
});

tak nevypíše vůbec nic. A přitom by měl ten selektor vypsat tolikrát, kolik je řádků v cílové tabulce. Nebo musím vymyslet způsob, jak funkci each zprovoznit s event místo selektoru - aby mi začal procházet řádky té cílové tabulky.
Václav M.
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 27. 1. 2022 22:48

Asi bude chyba u selektoru - začal bych nalezením tabulky dle ID, nebo jinak nalezl jedinečnou tabulku ( jinak se bude muset použít each i zde ) a až pak přidal tr a each.

Když pošleš příklad tabulky ( nemusí být obsah, jen struktura s class a id ) tak něco sesmolíme.
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod Václav M. 28. 1. 2022 09:30

Ta jedinečná hodnota je v atributu summary - ale jinak je to "kopie" textu tlačítka, kterým se spouští funkce, kterou je tabulka vytvořena.
Kód: Vybrat vše
<table summary="Medián kiometrů za měsíc dle roku" style="margin: -1px;">
   <tr>
      <td>...rok...</td>
      <td>...kilometry...</td>
   </tr>
</table>


Ten margin -1px je kvůli tomu, aby ta tabulka přesně sedla do buňky nadřazené tabulky (a nevytvářel se dvojitý okraj).
:arrow:
A výsledek se nezměnil ani poté, co jsem id z nadřazeného řádku zkopíroval i na tabulku s daty. Jasně, že ID má být jedinečné pro bez ohledu na to, na jaký porvek je použito ...

Kód: Vybrat vše
table#MedianKilometruZaJizduDleMesice > tr


Ale výsledek je stejný i v případě:
Kód: Vybrat vše
tr#MedianKilometruZaJizduDleMesice > table > tr
Václav M.
Junior
Uživatelský avatar

Další stránka

Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků