table/spread_oversized_table
Output a table on 2 x m pages as it is needed to fit it completely.
Download PHP Code Switch to Java Code Show Output
<?php
/*
* Spread oversized table:
* Output a table on 2 x m pages as it is needed to fit it completely.
*
* A table has a width which exceeds the width of the page. Therefore, output
* the table on a pair of pages with one page acting as the left and one page
* acting as the right page. Add pairs of pages until the table has been placed
* completely.
* Output each table instance twice with an appropriate clipping rectangle
* applied to the "left" or the "right" part, respectively. Use the "rewind"
* option of fit_table() to rewind the table to the state before the fit_table()
* call used to place the first table instance. Otherwise the table instance
* could not be placed a second time.
*
* In Acrobat, display the table as follows:
* Disable "View, Page Display, Show Cover Page in Two-Page View" if enabled.
* Choose "View, Page Display, Two Page View" to display two pages next to each
* other.
*
* Required software: PDFlib/PDFlib+PDI/PPS 9
* Required data: font
*/
/* This is where the data files are. Adjust as necessary. */
$searchpath = dirname(__FILE__,3)."/input";
$outfile = "";
$title = "Spread oversized Table";
$tbl = 0;
$pagewidth=421; $pageheight=595;
/* Number of rows and columns contained in the table */
$rowmax=50; $colmax=10;
/* Inside, outside, upper and lower page margins */
$inside=10; $outside=50; $top=20; $bottom=20;
/* Table width and height */
$tablewidth=2*($pagewidth-$outside-$inside);
$tableheight=$pageheight-$bottom-$top;
$lly=$bottom; $ury=$pageheight-$top;
$xmax = $pagewidth-$inside;
$xright = $outside;
$headertext = "Table header (centered across all columns)";
try {
$p = new pdflib();
$p->set_option("searchpath={" . $searchpath . "}");
/* This means we must check return values of load_font() etc. */
$p->set_option("errorpolicy=return");
if ($p->begin_document($outfile, "") == 0)
throw new Exception("Error: " . $p->get_errmsg());
$p->set_info("Creator", "PDFlib Cookbook");
$p->set_info("Title", $title );
/* -------------------
* Add the table cells
* -------------------
*/
/* In row 1 add the table header which spans all columns
*/
$row = 1; $col = 1;
$font = $p->load_font("NotoSerif-Regular", "unicode", "");
if ($font == 0)
throw new Exception("Error: " . $p->get_errmsg());
$optlist = "fittextline={position=center font=" . $font .
" fontsize=14} " . "margin=2 colspan=" . $colmax;
$tbl = $p->add_table_cell($tbl, $col, $row, $headertext, $optlist);
if ($tbl == 0)
throw new Exception("Error adding cell: " . $p->get_errmsg());
/* In row 2 and above add the respective column and row numbers */
for ($row++; $row <= $rowmax; $row++) {
for ($col = 1; $col <= $colmax; $col++)
{
$num = "Col " . $col . "/Row " . $row;
$optlist = "fittextline={font=" . $font . " fontsize=10} " .
"margin=2";
$tbl = $p->add_table_cell($tbl, $col, $row, $num, $optlist);
if ($tbl == 0)
throw new Exception("Error adding cell: " .
$p->get_errmsg());
}
}
/* Option list for fitting the table:
* define the first line as the header line;
* shade every other row; draw lines for all table cells
*/
$optlist = "header=1 fill={{area=rowodd fillcolor={gray 0.9}}} " .
"stroke={{line=other}} ";
/* --------------------------------------------------------------------
* Check if the table width fits completely on the page or if the table
* width has to distributed over two pages, i.e. the left and the right
* page
* --------------------------------------------------------------------
*/
/* Place the first table instance over both pages in blind mode. All
* calculations will be done but the table will not actually be placed.
* Then, retrieve the number of the last column (i.e. the vertical line)
* which still fits on the "left" page.
*/
$p->begin_page_ext($pagewidth, $pageheight, "");
$llx = $outside;
$urx = $llx+$tablewidth;
$result = $p->fit_table($tbl, $llx, $lly, $urx, $ury, $optlist . "blind");
if ($result == "_error")
throw new Exception ("Couldn't place table: " . $p->get_errmsg());
/* Query the x coordinate "xright" of the last column which fits in the
* fitbox on the "left" page
*/
for ($i = 1; $i <= $colmax; $i++)
{
/* Get the x coordinate of the vertical line with number #.
* "xvertline0" is the left table border.
*/
$x = $p->info_table($tbl, "xvertline" . $i);
if ($x > $xmax) {
break;
}
$xright = $x;
}
/* -------------------------------------------------------------
* Place the first half of the table instance on the "left" page
* -------------------------------------------------------------
*/
/* Since the table will be clipped on the right the inner margin of the
* left page may be increased. Use the "xshift" value to shift the table
* to the right so that the inner margin will become the default value
* again.
*/
$xshift = $pagewidth - $xright - $inside;
/* Using the x coordinate of the last column fitting on the "left" page
* set the clipping rectangle for the first columns of the table which
* will be placed on the left page.
*/
$llx = $outside + $xshift;
$widthleft = $xright - $outside;
$p->rect($llx, $lly, $widthleft, $tableheight);
$p->clip();
/* Place the table instance on the "left" page.
* Use the "rewind" option to rewind the table to the state before
* the last fit_table() call (which just happened in "blind" mode for
* calculation purposes).
* The table instance will be placed with the complete table width but
* it will be clipped according to the clipping rectangle to show only
* the first "xright" columns.
*/
$llx = $outside + $xshift;
$urx = $llx + $tablewidth;
$result = $p->fit_table($tbl, $llx, $lly, $urx, $ury, $optlist . " rewind=-1");
if ($result == "_error")
throw new Exception ("Couldn't place table : " . $p->get_errmsg());
$p->end_page_ext("");
/* ---------------------------------------------------------------
* Place the second half of the table instance on the "right" page
* ---------------------------------------------------------------
*/
$p->begin_page_ext($pagewidth, $pageheight, "");
/* Set the clipping rectangle for all further columns of the table which
* will be placed on the "right" page
*/
$llx = $inside;
$widthright = $tablewidth-$widthleft;
$p->rect($llx, $lly, $widthright, $tableheight);
$p->clip();
/* Place the table instance again on the "right" page.
* Use the "rewind" option to rewind the table to the state before
* the last fit_table() call (which has been used to place the first
* table instance). Otherwise this instance could not be placed a second
* time.
* The fitbox of the table instance is shifted to the left "outside"
* the page so that the last columns can be shown on the page.
* The table instance will be placed with the complete table width but
* it will be clipped according to the clipping rectangle to show only
* the last columns.
*/
$llx = $llx-$widthleft;
$urx = $inside+$widthright;
$result = $p->fit_table($tbl, $llx, $lly, $urx, $ury, $optlist . " rewind=-1");
if ($result == "_error")
throw new Exception ("Couldn't place table : " . $p->get_errmsg());
$p->end_page_ext("");
/* ---------------------------------------------------------------
* Place all further table instances on a left and right page each
* ---------------------------------------------------------------
*/
/* Loop until all of the table is placed; create new pages as long as
* more table instances need to be placed.
*/
while ($result == "_boxfull")
{
$p->begin_page_ext($pagewidth, $pageheight, "");
/* Set the clipping rectangle to place the first columns of the
* table on the left page
*/
$llx = $outside + $xshift;
$widthleft = $xright-$outside;
$p->rect($llx, $lly, $widthleft, $tableheight);
$p->clip();
/* Place the table instance on the "left" page */
$urx = $llx+$tablewidth;
$result = $p->fit_table($tbl, $llx, $lly, $urx, $ury, $optlist);
if ($result == "_error")
throw new Exception ("Couldn't place table : " . $p->get_errmsg());
$p->end_page_ext("");
$p->begin_page_ext($pagewidth, $pageheight, "");
/* Set the clipping rectangle to place all further columns of the
* table on the right page
*/
$llx = $inside;
$widthright = $tablewidth-$widthleft;
$p->rect($llx, $lly, $widthright, $tableheight);
$p->clip();
/* Place the table instance again on the "right" page */
$llx = $llx-$widthleft;
$urx = $inside+$widthright;
$result = $p->fit_table($tbl, $llx, $lly, $urx, $ury,
$optlist . " rewind=-1");
if ($result == "_error")
throw new Exception ("Couldn't place table : " . $p->get_errmsg());
$p->end_page_ext("");
}
/* Check the result; "_stop" means all is ok */
if (!$result == "_stop") {
if ($result == "_error")
throw new Exception ("Error when placing table: " .
$p->get_errmsg());
else
/* Any other return value is a user exit caused by the "return"
* option; this requires dedicated code to deal with.
*/
throw new Exception ("User return found in Textflow");
}
/* This will also delete Textflow handles used in the table */
$p->delete_table($tbl, "");
$p->end_document("");
$buf = $p->get_buffer();
$len = strlen($buf);
header("Content-type: application/pdf");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=spread_oversized_table.pdf");
print $buf;
} catch (PDFlibException $e) {
echo("PDFlib exception occurred:\n".
"[" . $e->get_errnum() . "] " . $e->get_apiname() .
": " . $e->get_errmsg() . "\n");
exit(1);
} catch (Throwable $e) {
echo("PHP exception occurred: " . $e->getMessage() . "\n");
exit(1);
}
$p = 0;
?>