ReportLab Two-Column TOC? - python

I have a PDF I am generating using ReportLab. I am using the standard TableOfContents flowable, but am trying to split it up into two columns, so it will all fit on the first page. the content will only ever be on one level, so I am not worried about odd-looking indentations.
Right now I have the PageTemplate using 2 Frames to create 2 columns on the first page. I get a
LayoutError: Flowable <TableOfContents at 0x.... frame=RightCol>...(200.5 x 720) too large on page 1 in frame 'RightCol'(200.5 x 708.0*)
Any ideas?

Well, color me embarrassed.
For anyone else having this problem, check your DocTemplate for allowSplitting. The default is 1, but I had changed mine to 0 and that was the reason.
*facepalm*

Related

How to have a horizontal scroll bar when a column in the output is really long when using Jupyter and Python

I am trying to use Jupyter + Python. Here is an example of the output
You can see the because the column 'correspondencedata' is too long, so it can not be shown fully in the output.
Can I change this so that a horizontal scroll bar will occur when a column has too long content?
You want to use pd.set_option('max_colwidth', nbr_pixel) before.
If you use a number big enough it will always show the entire content of your cells.
Like, pd.set_option('max_colwidth', 4000)
For more informations:
## To see the actual settings :
pd.get_option("display.max_colwidth")
## To reset with default value
pd.reset_option("max_colwidth")
Documentation

Pdf overlaying not working

I have been looking for a solution for this problem : I have two landscape-oriented A3 pdfs with images and I want to overlay them in a manner that the resulting pdf contains both images merged into one as if one of them was a watermark, but with the same density. Think of it as if about printing two different pdfs on one A3 sheet of paper, I want to get exactly that effect.
In other words - just came up with a way to express it - I would like to overlay two pdfs and for the upper layer, make all the "white" area transparent.
Basically, I just followed steps in any solution from this question:
overlay one pdf or ps file on top of another
The pdftk didn't work in my case. The resulting PDF displayed the pdf that was on the top layer, but the bottom layer was not seen. So, I proceeded to programming solution and downloaded pyPdf.
The code from the site was exactly an implementation of the desired solution:
from pyPdf import PdfFileReader,PdfFileWriter
output = PdfFileWriter()
input1 = PdfFileReader(file("b.pdf", "rb"))
page1 = input1.getPage(0)
watermark = PdfFileReader(file("a.pdf", "rb"))
page1.mergePage(watermark.getPage(0))
output.addPage(page1)
outputStream = file("c.pdf", "wb")
output.write(outputStream)
outputStream.close()
However, the result was the same as after using pdftk.
What am I doing wrong? Maybe this is not pdf merging, multimerging, stamping, overlaying etc but something else? If so, how is it called?
White in a pdf can be a result of two fundamental situations: Either it is the result of nothing being drawn there or of something being drawn there using an effective color white. PDFs of the first type can be given a background using those page merge methods, PDFs of the latter can't.
The content stream of the page of your sample file a.pdf starts like this:
1 0 0 -1 0 841 cm
0.45 0 0 0.45 0 0 cm
1 0 0 1 0 0 cm
0 0 m 2646 0 l 2646 1870 l 0 1870 l h
q
1 1 1 rg f
Q
The first three lines change the coordinate system for the operations to come to have its origin in the upper left corner, coordinate values increasing right and down, and one unit being 1/160 inch.
The fourth line draws a rectangle covering the whole page (actually even slightly more) and the sixth line fills that rectangle with white. (The fifth and seventh line merely save and restore the graphics state.)
By overlaying this PDF over a page of another one, therefore, this PDF first of all covers all the existing content of that page with a white rectangle.
Thus, your PDF cannot be given a background by simply adding the page content to the content of a background PDF page. You have to
either remove the lines 4 and 6 from that content first (maybe there is some checkbox in lucidchart allowing you to switch this white background rectangle on or of)
or use a different watermarking procedure (like doing it the other way around, overlaying your PDF page with the watermark PDF page using transparency).
PS: Strictly speaking those content lines already are erroneous: As soon as you start constructing a path (which in the sample above happens with 0 0 m, i.e. a move to position 0, 0), you may only use path construction (or path clipping) operations until you finally use a path drawing operator (f, i.e. fill, in your sample). Cf. this answer for a reference.
Thus, the color setting 1 1 1 rg (i.e. set fill color to RGB 100%, 100%, 100%) and the special graphic state manipulation q (save graphic state) operations are not allowed here. Depending on the PDF viewer, therefore, different things may happen while displaying that page, e.g. the filling operation might be completely ignored or merely the color setting operation might be and the current fill color (black?) might be used instead. One cannot count on all PDF viewers handling this error like Adobe Reader does.
Maybe lucidchart have already fixed that issue and an update suffices. Otherwise you should ask lucidchart to start doing their PDF charts right.

Display a huge sheet with QTableWidget

I need to display data using the PyQt class QTableWidget. But there could be dozens of thousand lines. Displaying the whole sheet makes the appli to hang...
So I found a solution consisting on loading data (meaning that the sheet is created) but hidding most of the rows and, when moving the scroll bar, show new rows and hidding previous ones.
In the bellow code, I setted self.rowsShown = 50 and at the init the lines from 1 to 50 are shown. And I previously did self.verticalScrollBar().actionTriggered.connect(self.refreshDisplay).
So the code is:
def refreshDisplay(self):
"""
This is to refresh the display when the scrollbar is moved
"""
# Minimum is reached and a previous row exists
if self.verticalScrollBar().value() <= self.verticalScrollBar().minimum() and self.isRowHidden(self.firstRowShown-1):# Minimum is reached and a previous row exists
for row in xrange(self.lastRowShown-1, self.lastRowShown):
self.hideRow(row)
self.lastRowShown -= 1
for row in xrange(self.firstRowShown-1, self.firstRowShown):
self.showRow(row)
self.firstRowShown -= 1
# Maximum is reached and a next row exists
if self.verticalScrollBar().value() >= self.verticalScrollBar().maximum() and self.isRowHidden(self.lastRowShown+1):
for row in xrange(self.firstRowShown, self.firstRowShown+1):
self.hideRow(row)
self.firstRowShown += 1
for row in xrange(self.lastRowShown, self.lastRowShown+1):
self.showRow(row)
self.lastRowShown += 1
This is working very well when I use the roll of the mouse or click on buttons of the scrollbar. But when I grab the slider or use the keypad to move the case selected, I'm blocked in the area shown.
Moreover, the size of the scrolling area correspond to the rows shown only. I would like to redifine it to set my own bar (for example with a size based on the real number of lines), so that I can move fastly to another part of the sheet. But the size of the scroll bar is always updated with the number of lines shown.
So, what I expect from you is to help me to resolve this two issues, OR give me another idea for displaying such huge sheet. Maybe I missed a module or class that already bear this functionnality of loading/showing lines whilemoving the cursor.
Thanks
I have written a tool that displays 10^6+ lines in an Excel-like table without resource problems. The solution is to use QTableView and QAbstractTableModel. You have to derive from QAbstractTableModel and implement the necessary functions it requires you to implement (I remember headerData and data, but I think there are more). You then plug the model into your view by doing view.setModel(model). More information how this is done can be found here.

How can I make wxTextCtrls in a FlexGridSizer all be 'x' lines high?

I have an array, of unknown length, of key:val pairs. Each pair occupies a row in a FlexGridSizer. The keys are in the first column, as wx.StaticTexts, and the vals are in the second column, as wx.TextCtrls.
The problem is that there isn't a lot of room available, and some of the vals are relatively long, and don't fit in the wx.TextCtrls. I would like to have all of the wx.TextCtrls be maybe 2 or 3 lines in height.
I've tried using style = wx.TE_MULTILINE, but that just adds a vertical scrollbar, as opposed to the default behaviour of scrolling horizontally with left/right/home/end etc.
Any ideas?
I suggest you use wxGrid.
http://docs.wxwidgets.org/2.9.2/overview_grid.html
According to the documentation for the wx.TextCtrl, you can apply the wx.HSCROLL style to it to make the control have a horizontal scrollbar, but this won't work on GTK1-based systems: http://xoomer.virgilio.it/infinity77/wxPython/Widgets/wx.TextCtrl.html
There's also an ExpandoTextCtrl that you might want to look at: from wx.lib.expando import ExpandoTextCtrl (see the wxPython demo for an example)
I ended up using FlexGridSizer. I made each of the val cells span across two rows, and added empty wx.Size()s below each key. The result is something like this:

how to group objects in reportlab, so that they stay together across new pages

I'm generating some pdf files using reportlab. I have a certain section that is repeated. It contains of a header and a table:
Story.append(Paragraph(header_string, styleH))
Story.append(table)
How can I group the paragraph with the table (in latex I would put them into the same environment) so that in case of a page brake, the paragraph and table stay together? Currently the paragraph sometimes floats at the end of one page and the table starts on top of the next page.
You can try to put them together in a KeepTogether flowable, like so:
Story.append(KeepTogether([Paragraph(header_string, styleH), table])
However be aware that, last I checked, the implementation was not perfect and would still split up items too frequently. I know it does a good job of keeping a single flowable together that would otherwise split, like if you were to say:
Story.append(KeepTogether(Paragraph(header_string, styleH))
then that paragraph would not get split unless it was impossible for it not to be.
If KeepTogether doesn't work for you, I'd suggest creating a custom Flowable with your paragraph and table inside it and then during layout make sure your custom Flowable subclass does not allow itself to be split up.
this is the solution that I found going through the reportlab source code:
paragraph = Paragraph(header_string, styleH)
paragraph.keepWithNext = True
Story.append(paragraph)
Story.append(table)
Using a ParagraphStyle might actually be better so i figured i'd add it to this super old answer.
Found this in their changelog after seeing #memyself's answer.
* `KeepWithNext` improved:
Paragraph styles have long had an attribute keepWithNext, but this was
buggy when set to True. We believe this is fixed now. keepWithNext is important
for widows and orphans control; you typically set it to True on headings, to
ensure at least one paragraph appears after the heading and that you don't get
headings alone at the bottom of a column.
header = ParagraphStyle(name='Heading1', parent=normal, fontSize=14, leading=19,
spaceAfter=6, keepWithNext=1)

Categories