Browse Source

adding a couple of reportlab explorations

master
manetta 4 years ago
parent
commit
d4762a36ee
  1. 4
      .gitignore
  2. BIN
      StanleySmith-Broman.ttf
  3. BIN
      cmunorm.ttf
  4. BIN
      cmunoti.ttf
  5. BIN
      exploring.pdf
  6. 99
      exploring.py
  7. 167
      hello.pdf
  8. 197
      language.txt
  9. 55
      make-multipaged-document-with-reportlab.py
  10. 105
      make-pdf-with-reportlab.py
  11. 93
      multipaged.pdf
  12. 3
      readme.md
  13. BIN
      reportlab-explorations.jpg
  14. 5456
      reportlab-userguide.pdf
  15. BIN
      tutorial-logo.png
  16. 68
      tutorial.pdf
  17. 28
      tutorial.py
  18. 88
      tutorial2.pdf
  19. 61
      tutorial2.py
  20. 87
      tutorial3.pdf
  21. 36
      tutorial3.py

4
.gitignore

@ -1,2 +1,2 @@
./reportlab-3.5.23/
./reportlab-3.5.23/*
reportlab-3.5.23/
reportlab-3.5.23/*

BIN
StanleySmith-Broman.ttf

Binary file not shown.

BIN
cmunorm.ttf

Binary file not shown.

BIN
cmunoti.ttf

Binary file not shown.

BIN
exploring.pdf

Binary file not shown.

99
exploring.py

@ -0,0 +1,99 @@
# https://www.youtube.com/watch?v=ZDR7-iSuwkQ
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm, mm
from reportlab.lib import colors
filename = 'exploring.pdf'
documenttitle = 'Testing'
title = 'Hello Reportlab'
subtitle = 'How are you doing?'
authors = 'You and Me and Many Others too'
textlines = [
'I am testing you...',
'I am testing you...',
'I am testing you...',
'What a day, no?',
'What a day, no?',
'What a day, no?',
'What a day, no?',
'What a day, no?',
'What a day, no?',
'Now we are together.'
]
image = 'tutorial-logo.png'
def drawRuler(pdf):
pdf.setFont('Courier', 8)
pdf.setFillColor(colors.blue)
# pdf.drawString(0*mm, 0*mm, 'xy10')
# pdf.drawString(10*mm, 10*mm, 'xy10')
pdf.drawString(20*mm, 160*mm, 'x20')
pdf.drawString(40*mm, 160*mm, 'x40')
pdf.drawString(60*mm, 160*mm, 'x60')
pdf.drawString(80*mm, 160*mm, 'x80')
pdf.drawString(100*mm, 160*mm, 'x100')
pdf.drawString(5*mm, 20*mm, 'y20')
pdf.drawString(5*mm, 40*mm, 'y40')
pdf.drawString(5*mm, 60*mm, 'y60')
pdf.drawString(5*mm, 80*mm, 'y80')
pdf.drawString(5*mm, 100*mm, 'y100')
pdf.drawString(5*mm, 120*mm, 'y120')
pdf.drawString(5*mm, 140*mm, 'y140')
pdf.drawString(5*mm, 160*mm, 'y160')
pdf = canvas.Canvas(filename)
pdf.setPageSize([110*mm, 170*mm])
pdf.setTitle(documenttitle)
pdf.setAuthor(authors)
drawRuler(pdf)
# for font in pdf.getAvailableFonts():
# print(font)
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase import pdfmetrics
pdfmetrics.registerFont(TTFont('stan', 'StanleySmith-Broman.ttf'))
pdfmetrics.registerFont(TTFont('concrete-reg', 'cmunorm.ttf'))
pdfmetrics.registerFont(TTFont('concrete-it', 'cmunoti.ttf'))
# Title
pdf.setFillColor(colors.black)
pdf.setFont('stan', 32)
# pdf.drawString(80, 720, title) # x, y (counting from bottom-left)
pdf.drawCentredString(60*mm, 150*mm, title) # x, y (counting from middle point string)
# Subtitle
pdf.setFillColorRGB(255, 0, 255)
pdf.setFont('concrete-it', 16)
pdf.drawCentredString(60*mm, 140*mm, subtitle)
# Line
pdf.setLineWidth(50)
pdf.line(20*mm, 100*mm, 100*mm, 115*mm) # start-x, start-y, end-x, end-y
# Text
pdf.setFont('concrete-reg', 9)
pdf.setFillColor(colors.red)
text = pdf.beginText(20*mm, 70*mm)
for line in textlines:
text.textLine(line)
pdf.drawText(text)
# Image
pdf.drawInlineImage(image, 70*mm, 40*mm, width=25*mm, height=25*mm) # x, y
# Other
pagenumber = pdf.getPageNumber()
pdf.drawCentredString(60*mm, 15*mm, str(pagenumber))
# Save
pdf.save()

167
hello.pdf

@ -0,0 +1,167 @@
%PDF-1.4
%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
1 0 obj
<<
/F1 2 0 R /F10 12 0 R /F11 13 0 R /F12 14 0 R /F13 15 0 R /F14 16 0 R
/F2 4 0 R /F3 5 0 R /F4 6 0 R /F5 7 0 R /F6 8 0 R /F7 9 0 R
/F8 10 0 R /F9 11 0 R
>>
endobj
2 0 obj
<<
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
>>
endobj
3 0 obj
<<
/Contents 21 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
4 0 obj
<<
/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
>>
endobj
5 0 obj
<<
/BaseFont /Courier-Bold /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font
>>
endobj
6 0 obj
<<
/BaseFont /Courier-BoldOblique /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font
>>
endobj
7 0 obj
<<
/BaseFont /Courier-Oblique /Encoding /WinAnsiEncoding /Name /F5 /Subtype /Type1 /Type /Font
>>
endobj
8 0 obj
<<
/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F6 /Subtype /Type1 /Type /Font
>>
endobj
9 0 obj
<<
/BaseFont /Helvetica-BoldOblique /Encoding /WinAnsiEncoding /Name /F7 /Subtype /Type1 /Type /Font
>>
endobj
10 0 obj
<<
/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F8 /Subtype /Type1 /Type /Font
>>
endobj
11 0 obj
<<
/BaseFont /Symbol /Name /F9 /Subtype /Type1 /Type /Font
>>
endobj
12 0 obj
<<
/BaseFont /ZapfDingbats /Name /F10 /Subtype /Type1 /Type /Font
>>
endobj
13 0 obj
<<
/BaseFont /Times-Bold /Encoding /WinAnsiEncoding /Name /F11 /Subtype /Type1 /Type /Font
>>
endobj
14 0 obj
<<
/BaseFont /Times-BoldItalic /Encoding /WinAnsiEncoding /Name /F12 /Subtype /Type1 /Type /Font
>>
endobj
15 0 obj
<<
/BaseFont /Times-Italic /Encoding /WinAnsiEncoding /Name /F13 /Subtype /Type1 /Type /Font
>>
endobj
16 0 obj
<<
/BaseFont /Times-Roman /Encoding /WinAnsiEncoding /Name /F14 /Subtype /Type1 /Type /Font
>>
endobj
17 0 obj
<<
/Contents 22 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
18 0 obj
<<
/PageMode /UseNone /Pages 20 0 R /Type /Catalog
>>
endobj
19 0 obj
<<
/Author (anonymous) /CreationDate (D:20200321123733-01'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20200321123733-01'00') /Producer (ReportLab PDF Library - www.reportlab.com)
/Subject (unspecified) /Title (untitled) /Trapped /False
>>
endobj
20 0 obj
<<
/Count 2 /Kids [ 3 0 R 17 0 R ] /Type /Pages
>>
endobj
21 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 519
>>
stream
GarVL9oId\%))O>kh%MHC<<n8?OQflo[F>7Su91.-/!j#rr4I9M'CRu0G/6[H[9^CJo&bilpiS"l;0Gn!1tY6oTaqDVIuQZ'rE)BAP0?"#oL'LWH&^9-1.G<M$3K(63_7V"b(pT$ja!hknR;.hE:L@JL5u$#9CblO2gQ)<Q(CXA"t3b\7C/;i<%/\\TY].=n*8aZm%F513N$=JQ]4$l>V0'kD-Dk3Sc%)C]=!<s0([''\\VF$-F%F<4Uu=Hs5IGpSW;N^otq(rpp`!^G%gPZYkZY)3$bG(Pg?*bJ2t%QD<uKl[+G!?]XV4*>:BUAX"63_8FNSa\HP`NBG6*Da4$<gTeOEX^W`i8"O4ApKkSCg;*;5'6oN@*]NCN8s/:=i0Ban>&TPd=Q"JepZHcpg"/&\^#+a>'t52g!`fL8gUq8od]tapda0O4$V/La`]'=TJJD&2Q/P1;Y]hnVN_/[db6i,4NGs]^UR`XmjIm(7T%fgm:3THV2<*?dh=JM7es7#uJ$4(N4T~>endstream
endobj
22 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 632
>>
stream
Gau1-95gRZ&BF88'[n#'>1R1&g[)0uFeq]q\t&I`=EdEWUWoQ3^\o(+,e/NK3B0PA=J#?gAf)&25g4A)k"fuUPtDc*28F>=5OK,F6M:K%@h.0:ggr:Kq[mMC(`-HDDi/jQN@5pS7^P*/X12.qUELLdSP-=K=Uid-/%k/IC+nPH>sj`5Y[2(C23\P4lh>S-Wq&0?SO<)TfgYAYi_:r"_?`u<>c!p5]dWR5kBC"O$_#5Rd'Ci,#ONr4cr\h9oligL]uW2?9[6V]Cq:X`+o0U".R2L1'L:Xm5f*R-OI-#I(P&9f%:BPBW663o&:rf*m-DYgHI13??BmrC_A6J11(B0o9OC@QCe&2pICS43(OJbA(HdP29t@%[Z;4J[nnX@5Z(Aju]Es/D(-,@JLG4FSqVe4'3Ahqt0oDF>HN!7_Jpr!X^R6jf4CWB;88s4.qto9(fnnV5,Sk&$AFM4Hhd?&hXi@KiY88D#YZ38L,I^Cd;9I$b0+TuUoUT*/i8_=aif;G.r7<F%b$p=u2nNHA"6\LuDn=%eBnJX(mPheO,[o*>DH7`,D:"p03cE%!`/e0.]taPCp1H<&SC>=&M9j3aRmS*lAL<DISViq.roEN$[q5/LT!+HteA1E8Z/PDu~>endstream
endobj
xref
0 23
0000000000 65535 f
0000000073 00000 n
0000000252 00000 n
0000000359 00000 n
0000000564 00000 n
0000000669 00000 n
0000000779 00000 n
0000000896 00000 n
0000001009 00000 n
0000001121 00000 n
0000001240 00000 n
0000001356 00000 n
0000001434 00000 n
0000001519 00000 n
0000001629 00000 n
0000001745 00000 n
0000001857 00000 n
0000001968 00000 n
0000002174 00000 n
0000002244 00000 n
0000002541 00000 n
0000002608 00000 n
0000003218 00000 n
trailer
<<
/ID
[<c2acc3d85d2e502e70887ee5c2591a1b><c2acc3d85d2e502e70887ee5c2591a1b>]
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
/Info 19 0 R
/Root 18 0 R
/Size 23
>>
startxref
3941
%%EOF

197
language.txt

@ -0,0 +1,197 @@
Language
Florian Cramer
Software and language are intrinsically related, since software may process language, and is constructed in language. Yet language means different things in
the context of computing: formal languages in which algorithms are expressed
and software is implemented, and in so-called “natural” spoken languages.
There are at least two layers of formal language in software: programming language in which the software is written, and the language implemented within
the software as its symbolic controls. In the case of compilers, shells, and macro
languages, for example, these layers can overlap. “Natural” language is what
can be processed as data by software; since this processing is formal, however,
it is restricted to syntactical operations.
While differentiation of computer programming languages as “artificial
languages” from languages like English as “natural languages” is conceptually
important and undisputed, it remains problematic in its pure terminology:
There is nothing “natural” about spoken language; it is a cultural construct
and thus just as “artificial” as any formal machine control language. To call programming languages “machine languages” doesn’t solve the problem either,
as it obscures that “machine languages” are human creations.
High-level machine-independent programming languages such as Fortran,
C, Java, and Basic are not even direct mappings of machine logic. If programming languages are human languages for machine control, they could
be called cybernetic languages. But these languages can also be used outside
machines—in programming handbooks, for example, in programmer’s dinner
table jokes, or as abstract formal languages for expressing logical constructs,
such as in Hugh Kenner’s use of the Pascal programming language to explain
aspects of the structure of Samuel Beckett’s writing.1
In this sense, computer control languages could be more broadly defined
as syntactical languages as opposed to semantic languages. But this terminology is not without its problems either. Common languages like English are
both formal and semantic; although their scope extends beyond the formal,
anything that can be expressed in a computer control language can also be expressed in common language. It follows that computer control languages are a
formal (and as such rather primitive) subset of common human languages.
Language
168
To complicate things even further, computer science has its own understanding of “operational semantics” in programming languages, for example
in the construction of a programming language interpreter or compiler. Just
as this interpreter doesn’t perform “interpretations” in a hermeneutic sense of
semantic text explication, the computer science notion of “semantics” defies
linguistic and common sense understanding of the word, since compiler construction is purely syntactical, and programming languages denote nothing
but syntactical manipulations of symbols.
What might more suitably be called the semantics of computer control languages resides in the symbols with which those operations are denoted in most
programming languages: English words like “if,” “then,” “else,” “for,” “while,”
“goto,” and “print,” in conjunction with arithmetical and punctuation symbols; in alphabetic software controls, words like “list,” “move,” “copy,” and
“paste”; in graphical software controls, such as symbols like the trash can.
Ferdinand de Saussure states that the signs of common human language are
arbitrary2 because it’s purely a cultural-social convention that assigns phonemes
to concepts. Likewise, it’s purely a cultural convention to assign symbols to machine operations. But just as the cultural choice of phonemes in spoken language
is restrained by what the human voice can pronounce, the assignment of symbols to machine operations is limited to what can be efficiently processed by the
machine and of good use to humans.3 This compromise between operability and
usability is obvious in, for example, Unix commands. Originally used on teletype terminals, the operation “copy” was abbreviated to the command “cp,”
“move” to “mv,” “list” to “ls,” etc., in order to cut down machine memory use,
teletype paper consumption, and human typing effort at the same time. Any
computer control language is thus a cultural compromise between the constraints of machine design—which is far from objective, but based on human
choices, culture, and thinking style itself 4—and the equally subjective user preferences, involving fuzzy factors like readability, elegance, and usage efficiency.
The symbols of computer control languages inevitably do have semantic
connotations simply because there exist no symbols with which humans would
not associate some meaning. But symbols can’t denote any semantic statements, that is, they do not express meaning in their own terms; humans metaphorically read meaning into them through associations they make. Languages
without semantic denotation are not historically new phenomena; mathematical formulas are their oldest example.
Language
169
In comparison to common human languages, the multitude of programming languages is of lesser significance. The criterion of Turing completeness
of a programming language, that is, that any computation can be expressed in
it, means that every programming language is, formally speaking, just a riff
on every other programming language. Nothing can be expressed in a Turingcomplete language such as C that couldn’t also be expressed in another Turingcomplete language such as Lisp (or Fortran, Smalltalk, Java . . .) and vice versa.
This ultimately proves the importance of human and cultural factors in programming languages: while they are interchangeable in regard to their control
of machine functions, their different structures—semantic descriptors, grammar and style in which algorithms can be expressed—lend themselves not
only to different problem sets, but also to different styles of thinking.
Just as programming languages are a subset of common languages, Turingincomplete computer control languages are a constrained subset of Turingcomplete languages. This prominently includes markup languages (such as
HTML), file formats, network protocols, and most user controls (see the entry
“Interface”) of computer programs. In most cases, languages of this type are
restrained from denoting algorithmic operations for computer security reasons—to prevent virus infection and remote takeover. This shows how the
very design of a formal language is a design for machine control. Access to
hardware functions is limited not only through the software application, but
through the syntax the software application may use for storing and transmitting the information it processes. To name one computer control language a
“programming language,” another a “protocol,” and yet another a “file format”
is merely a convention, a nomenclature indicating different degrees of syntactic restraint built into the very design of a computer control language.
In its most powerful Turing-complete superset, computer control language
is language that executes. As with magical and speculative concepts of language, the word automatically performs the operation. Yet this is not to be
confused with what linguistics calls a “performative” or “illocutionary” speech
act, for example, the words of a judge who pronounces a verdict, a leader giving
a command, or a legislator passing a law. The execution of computer control
languages is purely formal; it is the manipulation of a machine, not a social
performance based on human conventions such as accepting a verdict. Computer languages become performative only through the social impact of the
processes they trigger, especially when their outputs aren’t critically checked.
Joseph Weizenbaum’s software psychotherapist Eliza, a simple program that
Language
170
syntactically transforms input phrases, is a classical example,5 as is the 1987
New York Stock Exchange crash that involved a chain reaction of “sell” recommendations by day trading software.6
Writing in a computer programming language is phrasing instructions for
an utter idiot. The project of Artificial Intelligence is to prove that intelligence
is just a matter of a sufficiently massive layering of foolproof recipes—in linguistic terms, that semantics is nothing else but (more elaborate) syntax. As
long as A.I. fails to deliver this proof, the difference between common languages and computer control languages continues to exist, and language processing through computers remains restrained to formal string manipulations,
a fact that after initial enthusiasm has made many experimental poets since the
1950s abandon their experiments with computer-generated texts.7
The history of computing is rich with confusions of formal with common
human languages, and false hopes and promises that formal languages would
become more like common human languages. Among the unrealized hopes are
artificial intelligence, graphical user interface design with its promise of an “intuitive” or, to use Jef Raskin’s term, “humane interface,”8 and major currents
of digital art. Digital installation art typically misperceives its programmed
behaviorist black boxes as “interactive,” and some digital artists are caught in
the misconception that they can overcome what they see as the Western male
binarism of computer languages by reshaping them after romanticized images
of indigenous human languages.
The digital computer is a symbolic machine that computes syntactical language and processes alphanumerical symbols; it treats all data—including
images and sounds—as textual, that is, as chunks of coded symbols. Nelson
Goodman’s criteria of writing as “disjunct” and “discrete,” or consisting of separate single entities that differ from other separate single entities, also applies
to digital files.9 The very meaning of “digitization” is to structure analog data as
numbers and store them as numerical texts composed of discrete parts.
All computer software controls are linguistic regardless of their perceivable shape, alphanumerical writing, graphics, sound signals, or whatever else.
The Unix command “rm file” is operationally identical to dragging the file
into the trashcan on a desktop. Both are just different encodings for the same
operation, just as alphabetic language and morse beeps are different encodings
for the same characters. As a symbolic handle, this encoding may enable or
restrain certain uses of the language. In this respect, the differences between
ideographic-pictorial and abstract-symbolic common languages also apply
Language
171
to computer control languages. Pictorial symbols simplify control languages
through predefined objects and operations, but make it more difficult to link
them through a grammar and thus express custom operations. Just as a pictogram of a house is easier to understand than the letters h-o-u-s-e, the same is
true for the trashcan icon in comparison to the “rm” command. But it is difficult
to precisely express the operation “If I am home tomorrow at six, I will clean
up every second room in the house” through a series of pictograms. Abstract,
grammatical alphanumeric languages are more suitable for complex computational instructions.10 The utopia of a universal pictorial computer control
language (with icons, windows, and pointer operations) is a reenactment of
the rise and eventual fall of universal pictorial language utopias in the Renaissance, from Tommaso Campanella’s “Città del sole” to Comenius’ “Orbis pictus”—although the modern project of expressing only machine operations in
pictograms was less ambitious.
The converse to utopian language designs occurs when computer control languages get appropriated and used informally in everyday culture. Jonathan Swift
tells how scientists on the flying island of Lagado “would, for example, praise
the beauty of a woman, or any other animal . . . by rhombs, circles, parallelograms,
ellipses, and other “geometrical terms.” 11 Likewise, there is programming language poetry which, unlike most algorithmic poetry, writes its program source
as the poetical work, or crossbreeds cybernetic with common human languages.
These “code poems” or “codeworks” often play with the interference between
human agency and programmed processes in computer networks.
In computer programming and computer science, “code” is often understood either as a synonym of computer programming language or as a text
written in such a language. This modern usage of the term “code” differs from
the traditional mathematical and cryptographic notion of code as a set of formal transformation rules that transcribe one group of symbols to another group
of symbols, for example, written letters into morse beeps. The translation that
occurs when a text in a programming language gets compiled into machine
instructions is not an encoding in this sense because the process is not oneto-one reversible. This is why proprietary software companies can keep their
source “code” secret. It is likely that the computer cultural understanding of
“code” is historically derived from the name of the first high-level computer
programming language, “Short Code” from 1950.12 The only programming
language that is a code in the original sense is assembly language, the human-
Language
172
readable mnemonic one-to-one representation of processor instructions. Conversely, those instructions can be coded back, or “disassembled,” into assembly
language.
Software as a whole is not only “code” but a symbolic form involving cultural practices of its employment and appropriation. But since writing in
a computer control language is what materially makes up software, critical
thinking about computers is not possible without an informed understanding
of the structural formalism of its control languages. Artists and activists since
the French Oulipo poets and the MIT hackers in the 1960s have shown how
their limitations can be embraced as creative challenges. Likewise, it is incumbent upon critics to reflect the sometimes more and sometimes less amusing
constraints and game rules computer control languages write into culture.
Notes
1. Hugh Kenner, “Beckett Thinking,” in Hugh Kenner, The Mechanic Muse, 83–107.
2. Ferdinand de Saussure, Course in General Linguistics, ”Chapter I: Nature of the Linguistic
Sign.”
3. See the section, “Saussurean Signs and Material Matters,” in N. Katherine Hayles,
My Mother Was a Computer, 42–45.
4. For example, Steve Wozniak’s design of the Apple I mainboard was considered “a
beautiful work of art” in its time according to Steven Levy, Insanely Great: The Life and
Times of Macintosh, 81.
5. Joseph Weizenbaum, “ELIZA—A Computer Program for the Study of Natural
Language Communication between Man and Machine.”
6. Marsha Pascual, “Black Monday, Causes and Effects.”
7. Among them concrete poetry writers, French Oulipo poets, the German poet Hans
Magnus Enzensberger, and the Austrian poets Ferdinand Schmatz and Franz Josef
Czernin.
8. Jef Raskin, The Humane Interface: New Directions for Designing Interactive Systems.
9. According to Nelson Goodman’s definition of writing in The Languages of Art, 143.
Language
173
10. Alan Kay, an inventor of the graphical user interface, conceded in 1990 that “it
would not be surprising if the visual system were less able in this area than the mechanism that solve noun phrases for natural language. Although it is not fair to say that
‘iconic languages can’t work’ just because no one has been able to design a good one, it
is likely that the above explanation is close to truth.” This status quo hasn’t changed
since. Alan Kay, “User Interface: A Personal View,” in, Brenda Laurel ed. The Art of
Human-Computer Interface Design, Reading: Addison Wesley, 1989, 203.
11. Swift, Jonathan, Gulliver’s Travels, Project Gutenberg Ebook, available at http: //
www.gutenberg.org / dirs / extext197 / gltrv10.txt / .
12. See Wolfgang Hagen, “The Style of Source Codes.”
174

55
make-multipaged-document-with-reportlab.py

@ -0,0 +1,55 @@
from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.pagesizes import letter, A4
from reportlab.lib.units import mm, inch
from reportlab.lib.colors import pink, black, red, blue, green
def bodytext(canvas, textfile):
# Select unit
canvas.translate(mm, mm)
# Select font
canvas.setFont("Helvetica", 14)
# unit is point!
# Add text from document
textobject = canvas.beginText()
textobject.setTextOrigin(10*mm, 10*mm) # x, y ?
for line in textfile:
# textobject.textLine(line)
# does not move the cursor
textobject.textOut(line)
textobject.moveCursor(2*mm, 17.5) # positive value is moving the cursor down!
# move the cursor for the next line
textobject.setFillGray(0.4)
textobject.textOut('''With many apologies to the Beach Boys and anyone else who finds this objectionable''')
# draw text to canvas
canvas.drawText(textobject)
def moretext(canvas, text):
tobject = canvas.beginText()
canvas.drawText(tobject)
for line in text:
canvas.drawString(line)
page = Canvas("multipaged.pdf", pagesize=A4, bottomup=0, verbosity=1)
# flow text over pages
textfile = open('language.txt', 'r').readlines()
bodytext(page, textfile)
# add a new page
page.showPage()
# add more text
text = ['Hello you!','And hello me!','What else is there to say?']
bodytext(page, text)
# add a new page
page.showPage()
# save PDF
page.save()

105
make-pdf-with-reportlab.py

@ -0,0 +1,105 @@
from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.pagesizes import letter, A4
from reportlab.lib.units import mm, inch
from reportlab.lib.colors import pink, black, red, blue, green
def hello(canvas):
# Select unit
canvas.translate(mm, mm)
# Select font
canvas.setFont("Helvetica", 14)
# Select colors
canvas.setStrokeColorRGB(0.2,0.5,0.3)
canvas.setFillColorRGB(1,0,1)
# draw some lines
canvas.line(100*mm,100*mm,200*mm,200*mm)
canvas.line(25*mm,15*mm,50*mm,290*mm)
# canvas.line(x1,y1,x2,y2)
# draw a rectangle
canvas.rect(10*mm,65*mm,60*mm,80*mm, stroke=0, fill=1)
# make text go straight up
canvas.rotate(90)
# change color
canvas.setFillColorRGB(0,0,0.77)
# say hello (note after rotate the y coord needs to be negative!)
canvas.drawString(20*mm, 150*-mm, "Hello World")
# Undo the rotation
canvas.rotate(-90)
# Insert another string
canvas.drawString(10*mm, 10*mm, "Hello You")
# draw a grid
canvas.setStrokeColor(pink)
canvas.grid([50*mm, 75*mm, 100*mm, 125*mm], [30*mm, 60*mm, 90*mm, 120*mm, 150*mm])
# draw a circle
canvas.setFillColor(blue)
canvas.circle(150*mm, 250*mm, 20*mm, stroke=0, fill=1)
# Canvas shapes
# -------------
# canvas.grid(xlist, ylist)
# canvas.bezier(x1, y1, x2, y2, x3, y3, x4, y4)
# canvas.arc(x1,y1,x2,y2)
# canvas.rect(x, y, width, height, stroke=1, fill=0)
# canvas.ellipse(x1,y1, x2,y2, stroke=1, fill=0)
# canvas.wedge(x1,y1, x2,y2, startAng, extent, stroke=1, fill=0)
# canvas.circle(x_cen, y_cen, r, stroke=1, fill=0)
# canvas.roundRect(x, y, width, height, radius, stroke=1, fill=0)
textobject = canvas.beginText(25*mm, 25*mm)
canvas.drawText(textobject)
def fonts(canvas):
canvas.translate(mm, mm)
text = "Oh hello, you can use me in Reportlab !"
x = 50*mm
y = 5*mm
for font in canvas.getAvailableFonts():
canvas.setFont(font, 10)
canvas.drawString(x, y, text)
canvas.setFont("Helvetica", 10)
canvas.drawRightString(x-10, y, font+":")
y = y+13
page = Canvas("hello.pdf", pagesize=A4, bottomup=0, verbosity=1)
# filename
# pagesize=(595.27,841.89),
# = numbers in points
# bottomup=1,
# Some graphics systems (like PDF and PostScript)place (0,0) at the bottom left of the page
# bottomup = 0 --> top left
# bottomup = 1 --> bottom left
# !! The bottomup argument is deprecated and may be dropped in future
# pageCompression=0,
# pageCompression=1 --> compression is enabled
# encoding=rl_config.defaultEncoding,
# verbosity=0,
# verbosity=1 --> print log information while making a pdf
# encrypt=None
width, height = A4
# add hello page
hello(page)
# add a new page
page.showPage()
# add font page
fonts(page)
# add a new page
page.showPage()
# save PDF
page.save()

93
multipaged.pdf

File diff suppressed because one or more lines are too long

3
readme.md

@ -0,0 +1,3 @@
# Reportlab explorations
testing & exploring Reportlab to make PDFs with Python

BIN
reportlab-explorations.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

5456
reportlab-userguide.pdf

File diff suppressed because one or more lines are too long

BIN
tutorial-logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

68
tutorial.pdf

@ -0,0 +1,68 @@
%PDF-1.3
%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
1 0 obj
<<
/F1 2 0 R
>>
endobj
2 0 obj
<<
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
>>
endobj
3 0 obj
<<
/Contents 7 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 6 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
4 0 obj
<<
/PageMode /UseNone /Pages 6 0 R /Type /Catalog
>>
endobj
5 0 obj
<<
/Author (anonymous) /CreationDate (D:20200120170408-01'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20200120170408-01'00') /Producer (ReportLab PDF Library - www.reportlab.com)
/Subject (unspecified) /Title (untitled) /Trapped /False
>>
endobj
6 0 obj
<<
/Count 1 /Kids [ 3 0 R ] /Type /Pages
>>
endobj
7 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 279
>>
stream
Garo<6'$UO&;BTNMKeRJDA6^j7.c41@Q-Uu$l[G=*]D2JrVIAHNFjJR-^3eAmq^&g\*!$L*3p[,Wu1"8fE`6QK,*GK%fHsEK,2cDE:q4'h4,R4.RHOb(/p^c-8imTW@a")2#Bal5e\D6D`l3Vn/t:1%9$k5/X=`V\:ppFYZeQ=M!7M.HWR`+,'*/:\f]ET&_tV9DGo,a'\K2+eg&+.Xp3s?B11h0/+Ke;6`L`o)N^4Z[5mFZS(%4@9]/0a9\6t9#ui#<A[`s@qu!kkDEEbf:&~>endstream
endobj
xref
0 8
0000000000 65535 f
0000000073 00000 n
0000000104 00000 n
0000000211 00000 n
0000000414 00000 n
0000000482 00000 n
0000000778 00000 n
0000000837 00000 n
trailer
<<
/ID
[<1b1ca0dbec9400d8a6a0cf71696b6c4b><1b1ca0dbec9400d8a6a0cf71696b6c4b>]
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
/Info 5 0 R
/Root 4 0 R
/Size 8
>>
startxref
1206
%%EOF

28
tutorial.py

@ -0,0 +1,28 @@
# from: https://www.blog.pythonlibrary.org/2010/03/08/a-simple-step-by-step-reportlab-tutorial/
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
canvas = canvas.Canvas('tutorial.pdf', bottomup=0, pagesize=A4, )
width, height = A4
print(width) # 595.2755905511812
print(height) # 841.8897637795277
canvas.setLineWidth(.3)
canvas.setFont('Helvetica', 12)
canvas.drawString(25,50,'OFFICIAL COMMUNIQUE') # x-top-left, y-top-left
canvas.drawString(25,75,'OF ACME INDUSTRIES')
canvas.drawString(25,100,"12/12/2010")
canvas.line(25,125,550,125) # left-x, left-y, right-x, right-y
canvas.drawString(150,175,'AMOUNT OWED:')
canvas.drawString(150,200,"$1,000.00")
canvas.line(150,225,550,225)
canvas.drawString(150,275,'RECEIVED BY:')
canvas.line(150,300,550,300)
canvas.drawString(150,325,"JOHN DOE")
canvas.save()

88
tutorial2.pdf

File diff suppressed because one or more lines are too long

61
tutorial2.py

@ -0,0 +1,61 @@
import time
from reportlab.lib.enums import TA_JUSTIFY
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
doc = SimpleDocTemplate("tutorial2.pdf",pagesize=letter,
rightMargin=72,leftMargin=72,
topMargin=72,bottomMargin=18)
Story=[]
logo = "tutorial-logo.png"
magName = "Pythonista"
issueNum = 12
subPrice = "99.00"
limitedDate = "03/05/2010"
freeGift = "tin foil hat"
formatted_time = time.ctime()
full_name = "Mike Driscoll"
address_parts = ["411 State St.", "Marshalltown, IA 50158"]
im = Image(logo, 2*inch, 2*inch)
Story.append(im)
styles=getSampleStyleSheet()
styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY))
ptext = '<font size=12>%s</font>' % formatted_time
Story.append(Paragraph(ptext, styles["Normal"]))
Story.append(Spacer(1, 12))
# Create return address
ptext = '<font size=12>%s</font>' % full_name
Story.append(Paragraph(ptext, styles["Normal"]))
for part in address_parts:
ptext = '<font size=12>%s</font>' % part.strip()
Story.append(Paragraph(ptext, styles["Normal"]))
Story.append(Spacer(1, 12))
ptext = '<font size=12>Dear %s:</font>' % full_name.split()[0].strip()
Story.append(Paragraph(ptext, styles["Normal"]))
Story.append(Spacer(1, 12))
ptext = '<font size=12>We would like to welcome you to our subscriber base for %s Magazine! \
You will receive %s issues at the excellent introductory price of $%s. Please respond by\
%s to start receiving your subscription and get the following free gift: %s.</font>' % (magName,issueNum,subPrice,limitedDate,freeGift)
Story.append(Paragraph(ptext, styles["Justify"]))
Story.append(Spacer(1, 12))
ptext = '<font size=12>Thank you very much and we look forward to serving you.</font>'
Story.append(Paragraph(ptext, styles["Justify"]))
Story.append(Spacer(1, 12))
ptext = '<font size=12>Sincerely,</font>'
Story.append(Paragraph(ptext, styles["Normal"]))
Story.append(Spacer(1, 48))
ptext = '<font size=12>Ima Sucker</font>'
Story.append(Paragraph(ptext, styles["Normal"]))
Story.append(Spacer(1, 12))
doc.build(Story)

87
tutorial3.pdf

@ -0,0 +1,87 @@
%PDF-1.4
%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
1 0 obj
<<
/F1 2 0 R
>>
endobj
2 0 obj
<<
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
>>
endobj
3 0 obj
<<
/Contents 8 0 R /MediaBox [ 0 0 612 792 ] /Parent 7 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
4 0 obj
<<
/Contents 9 0 R /MediaBox [ 0 0 612 792 ] /Parent 7 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
5 0 obj
<<
/PageMode /UseNone /Pages 7 0 R /Type /Catalog
>>
endobj
6 0 obj
<<
/Author (\(anonymous\)) /CreationDate (D:20200120172414-01'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20200120172414-01'00') /Producer (ReportLab PDF Library - www.reportlab.com)
/Subject (\(unspecified\)) /Title (\(anonymous\)) /Trapped /False
>>
endobj
7 0 obj
<<
/Count 2 /Kids [ 3 0 R 4 0 R ] /Type /Pages
>>
endobj
8 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 3982
>>
stream
GasKDc*$,.'gUaRI0pL96/d<[Vi^rc0nJ+=5_'QF,:+"0+!9sZI?+[#V'N"pkO`E]mZfC2=#n_`?@P]Ds8MuO0RWUTr;Mc+0[7Mu5DNs$Xi'=/L-L'7r%q)Wqg1EfiAfuYQ[]G$J,K4!n^GhEFY1h^p_`HAqrM0,BoTSZ,@*O&5AM@$FW!BX%DNd14+.#]I/`QK2U(@MqK]VcqVRdNq),?&*SYA_9fh18oki,6:G8!1FaY::;Z$!1YA0Wglh"%[^KKUOXEcg4H<Ki'^(qadr*E^1c@$T)f;@S3Y2AGK-bip$e+tS"Y2AJBIu2?o^.+[kFkuXic62sodp2TL9Cu@[oN=iZ=\IGG;"Q1PIEJMPZaT'r./FX85&2\GXKChfXQWS2q@nfNC[8S"nL/#]IBmQ9qlD+?X<m_E-2O^>lr,>/'T5.d<:j<toI1K&$:USpQ$q4ap*j&7.271;7A$uq&,Z5TB5mU5S(=T8OePX6U/-oG:QakiW9D^3kgN!9I>Sbf)ARZ='n(s.T463G=a-K-7A!%<T42*XI8&`2U/*[aAY6@uT=%(Z[7$XpP^Nm-T463GN/Bf7M`uih:SI!Y[^+65b!*e%5)#_,U$/hkY3Xr1EX'o=S+a/6>,'>HU<d#;cW\ITKq_AJkYjr>T=%+[6ID]-oN>DOB5M4P@RZnUdAKh5=^0L#03^Ghk`\_2fk2naB._MD/^\2_AY2<:Vc`R?US?)gU/.KH;^hLDXmEC&Z;7a":SHuN./L$Ilaj!hS3cehVK^^+/^\2_d:Y&YB.[\e6ID]5oI6Q0ce>*hU$,E'qQ-gcZaR/8Z(b$fkYio+XK?p'cEj%Wh.LUdX$/t05"1>m7>a8tU/.PY:U?ck)ccMZ<qL**oP%:s.2I>h7A"2JI2WiK)AR[XF^=`g.VB<@Z>'/"s(<j5eeEZB7A2S-TgE=b@ZdTt1b.O[;8J&f/0Zs08o#t.'eD-U/2B)@:;rr+_6-GgQ[0-=C@3Qi-(.3%@ZdZmZmo+bC)F4E7]\L'C))_3%3nrlaAoV6<OD,CZj>5:Ji/Kr7Ct1$h<Ij*Z+6pJ\RZJpMFFdZ;63l&XC2fY)TCFO-rr0^22kuRUKGpL=OFEVe"Ts^.+U)0(%&U-q5?dq`TF>oG*?&C.i-*]7Bp<5Z%c,WBbY>-UKGnlehDt=N+,6!@R\IL9oEHiUKGD^<j_2Pa0QgU'Uu_W)c1-DXB6/e(<)/r`>V4NVGXFSN+,5N=MlQ<0T$SsM\Rh%2(a\CN+*6k=OHhN4f<T?GHoJsns5MC;63ntXBAE%=VRo='WYCOX!<O39oEHqMddEZ@SNV"djS8)]3*%H=N.":e#nTnQ?j6BD!ick;OKtY@Ss4/'J!3"CDb$Z7^4j,MA;+[%AR%C-s!]+<jXF/ZmaKZMD^?%7Ct1$gZhX(Z+6pJD.OL%MFFdZ;63l&XC2fY)TCFO-rr0^22kuRUKGpL=OFEVe"Ts^.+U)0(%&U-jetZ]`TF>o7[@0k.i-*]7Bp<5Z%c,WBbY>-UKGnlehDt=N+,6!@R\IL9oEHiUKGD^<j_2PVm@F5'Uu_W>?b]:XB6/e(<)/r`>V4NVGXFSN+,5N=MlQ<0T$SsM\Rh%2(a\CN+*6k=OF:0+/aE!;(T?Anm7Yc'Iss<MFFdZA[-teXD&Aa,GSAg.+U)022l!5b@3o`@SMbi%AR%C-s!^'=Pc\6MS%MR=*`-8X=2Z$.+YIJegu\Y/;dFZMUdhXZ)0spMFFe-7Br^eXD&BLg0Ldh;645(XD-;*moqr4-oQ:7pUn_E=Ks8T/;b/mM`$H&9qtf0)9%J&Z%c,W@2(4q(+WQ(CK_Ef(r[C_Z(bM?^E3%rU=e7$hX`L\@`>'DYp`YS/ClM422u'^A/$O4`>V4NL/G$c=fc:>XD(P5@2*Jo`JV+5MlT>[`TF>oSsNRo.i-*]7Bp<5Z%c,WBbY>-UKGnlehDt=N+,6!@R\IL9oEHiUKGD^<j_2PVl:_+'Uu_WHX:;]XB6/e(<)/r`>V4NVGXFSN+,5N=MlQ<0T$SsM\Rh%2(a\CN+*6k=OHiCaJBrs?0nnu]]Wj,'Pg_`CK;-b(<%a=`Ms]mlH#]%e"Ts`U0,C/=OS\L1l><#/lo5*<j=(([-Q_4XWBnFS%Hgi?=m'9=;38$`JTr")Fh!/;65b9@R[%o_^O(iMA7_$'eP>$/W)EE@L])7dB8DbNd;C:D!ieAH'q++@Ss4/'J!3"CDb$Z7^4j,MA;+[%AR%C-s!]+<jXF/ZmaKZMD^?%7Ct1$3U9O1Z+6pJk@GFJMFFdZ;63l&XC2fY)TCFO-rr0^22kuRUKGpL=OFEVe"Ts^.+U)0(%&U-H)a@H`Nj8.ms1<iZ!pS3=;38d(2Fc+RRXP?15Zg+@L])7_^JQm/69,/f!HjV0T%`H@R[m]IU)/87'X;']]WiA`JR*h@Ss4/=fc$GCDt1Ga=((GMD^?%%AR%QZ<5M[=OX!H_^O(iMA9tMVY=,Pi\'rX<Sm=&.uH27MDZoA22boYMdf\E@Wc3YXD(P5@Ss49;64IGCDt0lFr.2]'WY=MCYIWoZg(CUZ+6pJk@GFJMFFdZ;63l&XC2fY)TCFO-rr0^22kuRUKGpL=OFEVe"Ts^.+U)0(%&U-orLXq`TF>oSsNRo.i-*]7Bp<5Z%c,WBbY>-UKGnlehDt=N+,6!@R\IL9oEHiUKGD^<j_2PQ`2#p'Uu_WHX:;]XB6/e(<)/r`>V4NVGXFSN+,5N=MlQ<0T$SsM\Rh%2(a\CN+*6k=OF:0T9ad;;/GYMms1<iZ!pS3=;38d(2Fc+RRXP?15Zg+@L])7_^JQm/69,/f!HjV0T%`H@R]%,F/p[.#Fh4*4'j+"Xs-<:,"8RWdAg'+W``3!N@I70.loO;1,UO2'oPW%U/A8b7#d'jNJ^!?g5"^eB+PSlB2a)*9-bS8?;!Dn]p<nfHS+?sgP+YGm:,VTFr;#*Dm(`6hC]KQD\n:d\(=YE]Y1cEiU(*n_qTn)iU&u%nFkRN&$;mF^r$IgP<>A>Pk*ddV3DK<XE3@ZKVe<'S?Sm]iInV(%k"GKPn,5nXaE*::$'8!CFUE$=QbhX-S2C_iInVX_[1*.+&5p:q/F4!C0rp#B>@RWmnITrIB?\q0,U!QI_W,4Ks);YddukCR`[9"elI7/YT?en[BR%/RtW_b?S&:Xr*Eg&97F"I[%;1NeeVUBXJu+m@85ib$;7GU)Qm_g`rTXJIAa*2o"tI(Pb/,XF5`koV=]-JTVh:4!4A)a"/n_T*s3pnr"MCjjbEhN.R+#3kE6nf.';YG!4BcN!,="Ps4:6,r\(D>ci&.mnb+#NlDG/Y%WCd3_g?`99"_Qu:;4'd&9$pC`;=jD,2UmDM0JV2i_@+@GYbLNi@Va-nf>E0iXNSUGX&AThTgU&[Jt^6T<E`ni4g0)[m,;Rk&'nfa%uHg\*K+-rAEuob9)N.miOZXpX]qbK4eW\p:#Ze@@Xr`lQ@#;X+=oW*BX`,hCVt;cbeD,]H'*B96]rMn178hakK*6ChIt_G47%&h9"EfZ`nR"D[4V*g7>ks4:?4SnojLRN;^l=YEQ0Ymc<cn=kL?M[tA=%lV?:HSqX"&Grp6dVXEO4+;^?M4*`o4(67hDmGM."]9B^VB4:1&h@?-2\N>'uGS\<ujQ"k6kBD.@G47%&h9"EfZ`nR"D[4V*d[e#k4:>)3nog*&e(L;)*BX_umc<cn=kL?M[tA=%m7uLJSqX^:Grp6d`r>&Zf?)A,gh6@7>6"%o(L,d#2t2:Qh+@KbjsfJi]b@f[`iEUmT<RbNrTCndqpj<@I^XHk[M#dX<mJ7hf<gffosHPLgFI_J]]rO`GC*]-Qf;Sc[SQ;XjBdb2h:d3mmiqL0]_ks&a*2n%\:7ZOZ<LP1=8n*3X);KQgH3Bf'JI)+j(N?BpKG6->$K"O]e?`M??U,9=SK<<??U,9?s1'JFXu'OcaXToG&-9hrlDk+ioSeGGea5MV-@X1a8WP,s7lWEm_<(X%3PTNa3amM~>endstream
endobj
9 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1029
>>
stream
Gasb\c#2&c&;Bk($86sanUKOM&g/>Ud(BA\UoLm:h=19n53'Y7C(>!:VEW:lh!oUWTR,YPQQQ6V],C5.1iGU'j+B@A(nYV"k@aDcg`DH!rB&V=p-"e@n)eNb[<]<qm^<9FGKApdimZ4j_VBYF6+,6g=Y\c'F5G-A'OI:#hOJN`g(C?%(I%;F0CR'"L.#0k[]rY04`!/-b6MrGbGSnF^gUf`8)go@D#KE\[:=7_V1lE`rb.ub)u0Mf,ML(3+M)#<Dd.%U?MGDVG3o-L`cg^6^X-)`Fo2Z*WEJ].&9_q`R]hAI>mUhG&e\_$,]T*CTIOHf<7WOT8m(SITqEi%_,A,_8I8$0AZVRR6buTRJtRcsg8D:6KAl"KPVkZ3$%<L"r$3Q_8P%hg6buR<JtK,En<:*7-UY^GL4Z%N-%6JmprQXU:POIn$jAj%X0hmmkWKc3c:pb!PE=]M+i-r@JtI]AIPMW8A1[Mt=p7+s$[siFr+%5N8Qat"@>UV82>gu5prQA%PH]p9?LP`"F)K\h57%XF&eb*f,ksr%i[7+0:WA!YXB"bRYi$lr_,#f;T7eM>&si=7=MmphJtEGT57+BtId'!4Ia1ZCjsM=g:I9Z*KEOLG8c3*IprQY-PI1aH&f1CU./:n\n<:)p:Vm`/)/K#h;"0[Bi$Vs@c[EJ1)"6*Ue`j5WA@SZ[RI.R7)!rec:3IX'K3]kH>h<1*@pLD&<7aDke9-ksFPRKGkpgCBFIe)9Y(L8VlQ@).s-!4cV*;;ZHhg%Yf8lC1g&0\Jqh:`2>PjL6esGpMK=O@r>(-YBQPibHXg`U/2^+cZ><S<o\s?P`QfE,<\D22>kIbA^r@QIdMX#N1<;IPD4O9t/Ut#BekR"7>WM.'5H@kES][%AFTN[M'FQ#`CElj4-SrX<AOr^Of4Yi7'(>R<>*\Ro_P!s<P/+1rNjO=nc&]uESpMTE?:gR:HXp`u?.@7-D[GXWP>dDp_M+4luXg&U:,3>!<fNfI7b13T-m+,+RH+TD+>a?PfQhG"!5GE[:b5~>endstream
endobj
xref
0 10
0000000000 65535 f
0000000073 00000 n
0000000104 00000 n
0000000211 00000 n
0000000404 00000 n
0000000597 00000 n
0000000665 00000 n
0000000948 00000 n
0000001013 00000 n
0000005086 00000 n
trailer
<<
/ID
[<569dcf5552ddd7986559b775885e61ee><569dcf5552ddd7986559b775885e61ee>]
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
/Info 6 0 R
/Root 5 0 R
/Size 10
>>
startxref
6206
%%EOF

36
tutorial3.py

@ -0,0 +1,36 @@
from reportlab.platypus import LongTable, TableStyle, BaseDocTemplate, Frame, PageTemplate
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
def test():
doc = BaseDocTemplate(
"tutorial3.pdf",
pagesize=letter,
rightMargin=10,
leftMargin=10,
topMargin=10,
bottomMargin=10,
showBoundary=True)
elements = []
datas = []
for i, x in enumerate(range(1, 50)):
datas.append([i, x, i, x, i, x, i, x, i, x, i, x, i, x, i, x, i, x])
t = LongTable(datas)
tableStyle = [
('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
('BOX', (0, 0), (-1, -1), 0.25, colors.black),
]
t.setStyle(TableStyle(tableStyle))
elements.append(t)
frame = Frame(
doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='normal')
doc.addPageTemplates([PageTemplate(id='longtable', frames=frame)])
doc.build(elements)
if __name__ == '__main__':
test()
Loading…
Cancel
Save