2015-02-02 2 views
7

나는 이미이 질문을 던졌습니다. 아직 답변이 없으므로, 적극적으로 개발되고 fpdf python 라이브러리보다 나은 Reportlab을보고 싶습니다.Reportlab : pdf 파일에 바닥 글을 추가하는 방법

나는 이미 이것을 보았습니다 question 주어진 대답은이 blog post과 거의 비슷합니다. 여하튼, 스크립트는 오류로 가득차 있지만, 투표를하고 싶지 않습니다. OP가 받아 들였습니다. 그의 문제를 해결하는 것처럼 보였습니다. 누가 논쟁하겠습니까? 나는 다른 질문을하고 싶습니다.

당신이

from reportlab.pdfgen.canvas import Canvas 

를 가져올 필요가 우선하고, 그것이 Canvascanvas 아니라 다음 방금

Canvas.restoreState() 또는 Canvas.saveState()

어쩌면 더 오류가 할 수없는 I 차라리 다른 예를 사용하십시오. 어제 밤새 그 일을 할려고 노력했는데 할 수 없었습니다.

다른 방법으로 바닥 글을 만들 수 있습니까? 내가 묻고 싶은 특정 방법 this이다, 사람이 row[1] 뭔가

내가 Liberation Serif (12)를 사용하여, A4있는 LibreOffice와 문서에 계산, 그가 뭔가를 기록 row[0]에, 루프를 수행, 49 개 행이 있습니다. 글꼴 크기에 따라 평균 45 행이 있고 바닥 글 글꼴 크기가 8이라고 가정하면 x=row[45]과 같이 바닥 글을 삽입 한 다음 페이지 번호에 따라 x를 증가시킬 수 없습니까? 그게 훨씬 쉬운 해결책이 아니겠습니까?

파일의 끝이나 텍스트가 삽입 된 마지막 줄을 감지 할 수 있다고 생각합니다.

내 다른 질문을 참조하면 파워 포인트, Excel 및 PDF를 PDF로 변환 한 다음 바닥 글을 삽입한다는 것을 알 수 있습니다. 나는 그 다음 문서를 PDF 파일 작업을 쉽게 생각하기 때문에

리눅스와 윈도우 비밀 파워 포인트에서 작동 및 단어 엑셀 도서관이 경우, 바닥 글 다음 PDF로 변환 추가, 그것은, 좋은 것

+0

누군가 대답을하기 전까지는 os.system ("libreoffice --headless --invisible --convert-to doc' 또는 무엇인가 – Lynob

답변

11

우선 Reportlab은 훌륭합니다. pdfs를 생성하는 것으로 밝혀진 최고의 라이브러리.

예제를 시도하기 전에 reportlab를 설치하십시오 :

pip install reportlab 

당신이 multibuild와 문서를 렌더링 및 바닥 글을 추가 할 canvasmaker를 사용할 필요가 각주를 만들려면.

먼저, 두 페이지에 간단한 PDF 파일을 만들 수 있습니다 : PDF 파일이 제대로 만들어 졌는지

from reportlab.platypus import (SimpleDocTemplate, Paragraph, PageBreak) 
from reportlab.lib.styles import getSampleStyleSheet 
from reportlab.lib.pagesizes import LETTER 


if __name__ == '__main__': 

    # Content 
    styles = getSampleStyleSheet() 
    elements = [] 
    elements.append(Paragraph("Hello", styles["Normal"])) 
    elements.append(Paragraph("World", styles["Normal"])) 
    elements.append(PageBreak()) 
    elements.append(Paragraph("You are in page 2", styles["Normal"])) 

    # Build 
    doc = SimpleDocTemplate("my_file.pdf", pagesize=LETTER) 
    doc.build(elements) 

확인합니다.이제

의 마지막 줄에 multibuild하는 라인과 페이지 번호를 표시하는 바닥 글을 그리고 빌드를 변경하는 캔버스 클래스를 추가 할 수 있습니다 :

이 multibuild에서
from reportlab.pdfgen import canvas 
from reportlab.platypus import (SimpleDocTemplate, Paragraph, PageBreak) 
from reportlab.lib.styles import getSampleStyleSheet 
from reportlab.lib.pagesizes import LETTER 


class FooterCanvas(canvas.Canvas): 

    def __init__(self, *args, **kwargs): 
     canvas.Canvas.__init__(self, *args, **kwargs) 
     self.pages = [] 

    def showPage(self): 
     self.pages.append(dict(self.__dict__)) 
     self._startPage() 

    def save(self): 
     page_count = len(self.pages) 
     for page in self.pages: 
      self.__dict__.update(page) 
      self.draw_canvas(page_count) 
      canvas.Canvas.showPage(self) 
     canvas.Canvas.save(self) 

    def draw_canvas(self, page_count): 
     page = "Page %s of %s" % (self._pageNumber, page_count) 
     x = 128 
     self.saveState() 
     self.setStrokeColorRGB(0, 0, 0) 
     self.setLineWidth(0.5) 
     self.line(66, 78, LETTER[0] - 66, 78) 
     self.setFont('Times-Roman', 10) 
     self.drawString(LETTER[0]-x, 65, page) 
     self.restoreState() 


if __name__ == '__main__': 

    # Content 
    styles = getSampleStyleSheet() 
    elements = [] 
    elements.append(Paragraph("Hello", styles["Normal"])) 
    elements.append(Paragraph("World", styles["Normal"])) 
    elements.append(PageBreak()) 
    elements.append(Paragraph("You are in page 2", styles["Normal"])) 

    # Build 
    doc = SimpleDocTemplate("my_file.pdf", pagesize=LETTER) 
    doc.multiBuild(elements, canvasmaker=FooterCanvas) 

당신은 또한 처음에 다른 캔버스를 지정할 수 있습니다 다음 페이지로 이동하십시오.

doc.multiBuild(Elements, onFirstPage=myFirstPage, onLaterPages=myLaterPages) 

희망 사항.

편집

목표는 이제 기존의 PDF 파일에 바닥 글을 추가하는 것입니다. 불행히도, 이것은 Reportlab (적어도 오픈 소스 버전에서만 가능합니다. proffesional 버전에는이 기능이 있습니다). "페이지를 추출, 원본 PDF를 열고, 그리고 :

Firt, 우리는 pdfrw 이제

pip install pdfrw 

우리가이 일을 기존 PDF로 바닥 글을 추가 할 수 있습니다 약간 조리법에 추가 할 필요가 "그림 새로운 PDF로 바닥 글 따라 페이지, 한 번에 한 페이지 :

from reportlab.pdfgen.canvas import Canvas 
from pdfrw import PdfReader 
from pdfrw.toreportlab import makerl 
from pdfrw.buildxobj import pagexobj 

input_file = "my_file.pdf" 
output_file = "my_file_with_footer.pdf" 

# Get pages 
reader = PdfReader(input_file) 
pages = [pagexobj(p) for p in reader.pages] 


# Compose new pdf 
canvas = Canvas(output_file) 

for page_num, page in enumerate(pages, start=1): 

    # Add page 
    canvas.setPageSize((page.BBox[2], page.BBox[3])) 
    canvas.doForm(makerl(canvas, page)) 

    # Draw footer 
    footer_text = "Page %s of %s" % (page_num, len(pages)) 
    x = 128 
    canvas.saveState() 
    canvas.setStrokeColorRGB(0, 0, 0) 
    canvas.setLineWidth(0.5) 
    canvas.line(66, 78, page.BBox[2] - 66, 78) 
    canvas.setFont('Times-Roman', 10) 
    canvas.drawString(page.BBox[2]-x, 65, footer_text) 
    canvas.restoreState() 

    canvas.showPage() 

canvas.save() 

부인 : 리눅스가 입력 파일로 Reportlab에 의해 생성 된 PDF 파일을 사용하여 테스트. 아마 임의의 pdf 파일에서 작동하지 않을 것입니다.

+0

답변을 주셔서 감사합니다. 내일 답변을 수락하겠습니다. 당신에게 뭔가 물어 보니 페이지 꼬리말이 페이지 바로 가기를 호출하자마자 삽입되는 것입니까? 그렇다면 기존 파일을 사용하고 있기 때문에 저에게 효과가 없을 것입니다. 이전의 질문을 참조하십시오. 내가 수동으로 삽입하지 않기 때문에 페이지가 끝나는 시점을 알 수있는 방법이 없다. pdf에서 페이지를 감지하는 기능이없는 한 전체 루프를 for 루프를 사용하고있다. – Lynob

+0

OnlaterPages – Lynob

+0

필자가 손으로 쓰지 않기 때문에 요소 []에있는 파일의 각 페이지를로드하는 방법 – Lynob

관련 문제