2 回答

TA貢獻(xiàn)1798條經(jīng)驗(yàn) 獲得超7個(gè)贊
在你調(diào)用Paragraph.wrapor 之后Paragraph.wrapOn,你有一個(gè)叫做blParaavailable的屬性,它有一個(gè)叫做lines列表的屬性。你可以使用它的長(zhǎng)度。像這樣:
from reportlab.lib.enums import TA_JUSTIFY
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.units import mm
from reportlab.pdfgen.canvas import Canvas
from reportlab.platypus import Paragraph
canvas = Canvas("test.pdf")
drawText = "The Avengers become divided, both over how to approach Loki and the revelation that S.H.I.E.L.D. plans to harness the Tesseract to develop weapons as a deterrent against hostile extraterrestrials. As the group argues, Barton and Loki's other possessed agents attack the Helicarrier, disabling one of its engines in flight and causing Banner to transform into the Hulk. Stark and Rogers work to restart the damaged engine, and Thor attempts to stop the Hulk's rampage. Romanoff reluctantly fights Barton, and knocks him unconscious, breaking Loki's mind control. Loki escapes after killing Coulson and ejecting Thor from the airship, while the Hulk falls to the ground after attacking a S.H.I.E.L.D. fighter jet. Fury uses Coulson's death to motivate the Avengers into working as a team. Stark and Rogers realize that for Loki, simply defeating them will not be enough; he needs to overpower them publicly to validate himself as ruler of Earth. Loki uses the Tesseract, in conjunction with a device Selvig built, to open a wormhole above Stark Tower to the Chitauri fleet in space, launching his invasion."
availWidth, availHeight = 190*mm, A4[1]
style = ParagraphStyle("justifies", alignment=TA_JUSTIFY, fontSize=11, leading=12)
par = Paragraph(drawText, style=style)
par.wrap(availWidth, availHeight)
par.drawOn(canvas, 10*mm, A4[1]-10*mm-par.height)
print(len(par.blPara.lines)) # 11
canvas.save()
還有simpleSplit它做同樣的工作,額外的好處是更容易獲得每一行的文本。
from reportlab.lib.utils import simpleSplit
lines = simpleSplit(drawText, style.fontName, style.fontSize, availWidth)

TA貢獻(xiàn)1982條經(jīng)驗(yàn) 獲得超2個(gè)贊
我剛剛遇到了這個(gè)問(wèn)題,同時(shí)也在尋找一些簡(jiǎn)單的方法來(lái)完成您的要求。不幸的是我沒(méi)有找到答案,所以我試圖把一些東西放在一起來(lái)讓它工作。它不漂亮,但它有效!
我剛剛在您的 canv.save() 方法調(diào)用之后添加了此代碼:
pixelRatio = 1.333333 # 1 point = 1.333333 pixels
# https://websemantics.uk/articles/font-size-conversion/
# http://www.endmemo.com/sconvert/pixelpoint.php#targetText=Pixel%E2%86%94Point%201%20Point,Twip%201%20Pixel%20%3D%2015%20Twip
fontLineHeight = styles["Justify"].fontSize * pixelRatio
boxWidth = width
boxHeight = height
boxLines = int(72/fontLineHeight)
boxLRBuffer = 0 # Adjust this to whatever inside margin/padding you have in your box
boxPixelCapacity = boxWidth * boxLines - boxLRBuffer # Total pixels in the box
# A list to hold the lines of text
textLines = []
# A pointer to indicate which character is being evaluated
position = len(drawText)
# Make a copy of the original string so as to not modify it
tempString = drawText
# This is a dummy string used to test the width of the string
testString1 = tempString
# Another dummy string to hold what is not being split into a line
# testString2 will be build going backwards from the last character
# to the character right after the line split
testString2 = ''
# Boolean flag to get out of the while loop
done = False
while not done:
# Use pdfmetrics to get the line width in points based upon the fontName and fontSize used
if pdfmetrics.stringWidth(testString1, styles["Justify"].fontName, styles["Justify"].fontSize, 'utf8') > boxWidth-boxLRBuffer*2:
# Since the line is too long, move backwards through the string until an appropriate size is found
# by decreasing the pointer position. Spaces also take space.
position -= 1
if position >= 0:
#since the the pointer has not reached the beginning of testString1
testString1 = testString1[:position] # remove the last character from testString1
testString2 = tempString[position:] # add the next character to testString2 for later use
# Since testString1 now fits within the stringWidth
# it must be checked to see if this is the last line
# being processed.
elif testString1 == testString2:
# This must be the last line since it equals testString2
textLines.append(testString2.strip())
break
# This is not the last line of text, so now work backwards in
# the string to find a space so the line can be split
elif ' ' in testString1:
while testString1[position:] != ' ' and position >= 0:
testString1 = testString1[:position]
testString2 = tempString[position:]
position -= 1
if len(testString1):
textLines.append(testString1.strip())
else:
textLines.append(testString2.strip())
break
tempString = tempString[position:].strip()
testString1 = tempString
position = len(tempString)
elif testString1 == "":
# It's done
break
else:
# The text does not exceed the stringWidth
textLines.append(testString1)
# testString2 must be checked and if empty then it's done
if testString2 == "":
done = True
else:
tempString = tempString[position:].strip()
testString1 = tempString
position = len(tempString)
print(len(textLines))
我愿意接受使此代碼更好或更精簡(jiǎn)的建議。
添加回答
舉報(bào)