3
$\begingroup$

I have a large data set which I need to export as a table to a PDF file. At the moment, I do this by exporting as CSV, applying some styling in Excel (display as table, autofit column width, etc.), and then exporting as PDF. I would like to be able to do it in one step directly from Mathematica.

NotebookPrint combined with the new (v10.3) function TextGrid seems to be able to present the data quite nicely, but the presentation is poor is when the table spans multiple pages. Is there any way to convince Mathematica to repeat column headings on each page, or to determine where page breaks will occur, so that the repeated headings can be inserted?


For example, here's some data:

data = Select[ExampleData[{"Dataset", "Titanic"}] // Normal, 
    NumericQ[#age] &][[;; 100]];

Extract the keys and put the data into a list of lists:

headings = Keys[First[data]];
dataAsTable = Outer[Lookup[#1, #2, ""] &, data, headings, 1];

I have tried the following two, which (unlike Export) produce a PDF document with sensible page sizes and with the table split between pages:

NotebookPrint[
 TableForm[dataAsTable, TableHeadings -> {None, headings}] // 
  OutputForm, "temp.pdf"];

NotebookPrint[
 TextGrid[Prepend[dataAsTable, headings], Frame -> All, 
  Background -> {None, {LightGray, {None}}}], "temp.pdf"];

But in both cases, the way the grid is split at the page break is quite ugly, and there seems to be no way to repeat the headers on each page.

$\endgroup$
  • $\begingroup$ One way to do this is to write the table as HTML (using <thead> elements so that headers are repeated) and then to print the HTML to PDF, for example using a headless Chrome instance. I will write a proper answer when I have implemented this. $\endgroup$ – Stephen Powell Nov 2 '18 at 10:42
1
$\begingroup$

As I noted in a comment, this can be done by exporting the table as HTML and printing to PDF. Here's an example:

SetDirectory[NotebookDirectory[]];
htmlFile = File["Table.html"];
pdfFile = File["Table.pdf"];

rowTemplate = 
  StringTemplate[
   "<tr><td>`class`</td><td>`age`</td><td>`sex`</td><td>`survived`</td></tr>\n"];

headerRow = 
  "<tr><th>class</th><th>age</th><th>sex</th><th>survived</th></tr>";

Export[ExpandFileName[htmlFile], 
  StringJoin @@ 
   Flatten[{"<table><thead>", headerRow, "</thead><tbody>", 
     rowTemplate /@ data[[;; 100]], "</tbody></table>"}], "Text"];

RunProcess[{"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
   "--headless", 
   StringTemplate["--print-to-pdf=\"``\""]@ExpandFileName[pdfFile], 
   ExpandFileName[htmlFile]}];
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.