在Python中

时间:2018-02-19 09:53:24

标签: python pdf reportlab

我有一个python脚本,它使用reportlab platypus将.csv文件中的文本消息数据写入PDF中的表。它只将表的最后一行写入单元格。在此之前它忽略所有其他行。它写入PDF的唯一一行是以黄色突出显示的excel片段中显示的最后一行。如图所示,它还包含了将其写入PDF的内容。

enter image description here

enter image description here

它还会在三到四页中创建PDF,推断它正试图为整个表格腾出空间,但却不会写出来。这是我到目前为止一直在使用的代码。我想以Excel片段中显示的相同格式将其写入PDF文档。我应该如何重构我的代码呢?

# Script to generate a PDF report after data has been parsed into smsInfo.csv file

# import statements
import requests
from reportlab.lib import colors
from reportlab.lib.pagesizes import *
from reportlab.platypus import *
from reportlab.lib.styles import getSampleStyleSheet
import csv
import os
import datetime

now = datetime.datetime.now()

# Get de work directory
cwd = os.getcwd()

# Introduction text
line1 = 'LYIT MOBILE FORENSICS DIVISION'
line2 = 'Date: ' + now.strftime("%d-%m-%y")
line3 = 'Case Number: 10'
line4 = 'This forensic report on sms card data has been compiled by the forensic'
line5 = 'examiner in conclusion to the investigation into the RTA'
line6 = 'case which occurred on 23/01/2018.'


#PDF document layout
table_style = TableStyle([('ALIGN',(1,1),(-2,-2),'RIGHT'),
                       ('TEXTCOLOR',(1,1),(-2,-2),colors.red),
                       ('VALIGN',(0,0),(0,-1),'TOP'),
                       ('TEXTCOLOR',(0,0),(0,-1),colors.blue),
                       ('ALIGN',(0,-1),(-1,-1),'CENTER'),
                       ('VALIGN',(0,-1),(-1,-1),'MIDDLE'),
                       ('TEXTCOLOR',(0,-1),(-1,-1),colors.green),
                       ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
                       ('BOX', (0,0), (-1,-1), 0.25, colors.black),
                       ])
styles = getSampleStyleSheet()
styleNormal = styles['Normal']
styleHeading = styles['Heading1']
styleHeading2 = styles['Heading2']
styleHeading.alignment = 1 # centre text (TA_CENTRE)

#Configure style and word wrap
s = getSampleStyleSheet()
s = s["BodyText"]
s.wordWrap = 'CJK'

# File that must be written to report
with open('H:\College Fourth Year\Development Project\Final Year Project 2018\ExtractedEvidence\smsInfo.csv', "r") as csvfile:
    reader = csv.reader(csvfile)
    lista = list(reader)

headers = lista[0]

conteo = 1

for numRecord in range(1,len(lista)):

    record1 = lista[numRecord]

    data = list()
    emptyRecords = list()
    records = list()
    header = list()

    countRecords = 0

    for line in record1:

        if line == '':
            emptyRecords.append(line)
        else:
            records.append(line)
            header.append(headers[countRecords])

            data.append([str(headers[countRecords]), str(line)])

        countRecords = countRecords + 1

    data2 = [[Paragraph(cell, s) for cell in row] for row in data]
    t = Table(data2)
    t.setStyle(table_style)

    elements = []

    # Name of file
    fileName = cwd + '\\' + 'Forensic Reports\\SMS Data Report' + '.pdf'

    conteo = conteo + 1

    archivo_pdf = SimpleDocTemplate(fileName, pagesize = letter, rightMargin = 40, leftMargin = 40, topMargin = 40, bottomMargin = 28)

    #Send the data and build the file
    elements.append(Paragraph(line1, styleNormal))
    elements.append(Paragraph(line2, styleNormal))
    elements.append(Paragraph(line3, styleNormal))
    elements.append(Spacer(inch, .25*inch))
    elements.append(Paragraph(line4, styleNormal))
    elements.append(Paragraph(line5, styleNormal))
    elements.append(Paragraph(line6, styleNormal))
    elements.append(Spacer(inch, .25*inch))
    elements.append(t)

    archivo_pdf.build(elements)
    print ('SMS Data Forensic Report Generated!')

1 个答案:

答案 0 :(得分:5)

当前脚本似乎会覆盖CSV每行的相同PDF文件。下面显示的修改后的脚本生成表格,如电子表格中所示。我做了一些重大更改,因此您需要修改文件路径,格式,内容等,以适合您的应用程序。新代码还包括列宽,并删除一些看似不必要的字符。

生成的PDF的示例

PDF Example

用于测试的CSV数据:

['ID','Incoming Number','Date & Time','Read','Sent/Replied','Body','Seen']
(1,'555-555-5555','23-01-2018 17:03:52',1,1,'Where are you at? Are you on your way yet?',1)
(2,'555-555-5555','23-01-2018 17:04:08',1,2,'Yes I am driving at the moment',1)
(3,'555-555-5555','23-01-2018 17:04:34',1,1,'Be here soon or I'm going to call you',1)
(4,'555-555-5555','23-01-2018 17:05:10',1,2,'Yes I will try and pick up the speed and make up time. I'm breaking the speed limit already.',1)
(5,'555-555-5555','23-01-2018 17:05:46',1,1,'Ok',1)

修改后的Python脚本

表格样式代码比帮助演示单元格范围的工作方式所需的时间长。

import csv
import datetime
from reportlab.lib.units import cm, inch
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter
from reportlab.platypus import *
from reportlab.lib.styles import getSampleStyleSheet

# Data from CSV
with open('smsInfo.csv', "r") as csvfile:
    data = list(csv.reader(csvfile))

elements = []

# PDF Text
# PDF Text - Styles
styles = getSampleStyleSheet()
styleNormal = styles['Normal']

# PDF Text - Content
line1 = 'LYIT MOBILE FORENSICS DIVISION'
line2 = 'Date: {}'.format(datetime.datetime.now().strftime("%d-%m-%y"))
line3 = 'Case Number: 10'
line4 = 'This forensic report on sms card data has been compiled by the forensic'
line5 = 'examiner in conclusion to the investigation into the RTA'
line6 = 'case which occurred on 23/01/2018.'

elements.append(Paragraph(line1, styleNormal))
elements.append(Paragraph(line2, styleNormal))
elements.append(Paragraph(line3, styleNormal))
elements.append(Spacer(inch, .25 * inch))
elements.append(Paragraph(line4, styleNormal))
elements.append(Paragraph(line5, styleNormal))
elements.append(Paragraph(line6, styleNormal))
elements.append(Spacer(inch, .25 * inch))

# PDF Table
# PDF Table - Styles
# [(start_column, start_row), (end_column, end_row)]
all_cells = [(0, 0), (-1, -1)]
header = [(0, 0), (-1, 0)]
column0 = [(0, 0), (0, -1)]
column1 = [(1, 0), (1, -1)]
column2 = [(2, 0), (2, -1)]
column3 = [(3, 0), (3, -1)]
column4 = [(4, 0), (4, -1)]
column5 = [(5, 0), (5, -1)]
column6 = [(6, 0), (6, -1)]
table_style = TableStyle([
    ('VALIGN', all_cells[0], all_cells[1], 'TOP'),
    ('LINEBELOW', header[0], header[1], 1, colors.black),
    ('ALIGN', column0[0], column0[1], 'LEFT'),
    ('ALIGN', column1[0], column1[1], 'LEFT'),
    ('ALIGN', column2[0], column2[1], 'LEFT'),
    ('ALIGN', column3[0], column3[1], 'RIGHT'),
    ('ALIGN', column4[0], column4[1], 'RIGHT'),
    ('ALIGN', column5[0], column5[1], 'LEFT'),
    ('ALIGN', column6[0], column6[1], 'RIGHT'),
])

# PDF Table - Column Widths
colWidths = [
    0.7 * cm,  # Column 0
    3.1 * cm,  # Column 1
    3.7 * cm,  # Column 2
    1.2 * cm,  # Column 3
    2.5 * cm,  # Column 4
    6 * cm,  # Column 5
    1.1 * cm,  # Column 6
]

# PDF Table - Strip '[]() and add word wrap to column 5
for index, row in enumerate(data):
    for col, val in enumerate(row):
        if col != 5 or index == 0:
            data[index][col] = val.strip("'[]()")
        else:
            data[index][col] = Paragraph(val, styles['Normal'])

# Add table to elements
t = Table(data, colWidths=colWidths)
t.setStyle(table_style)
elements.append(t)

# Generate PDF
archivo_pdf = SimpleDocTemplate(
    'SMS Data Report.pdf',
    pagesize=letter,
    rightMargin=40,
    leftMargin=40,
    topMargin=40,
    bottomMargin=28)
archivo_pdf.build(elements)
print('SMS Data Forensic Report Generated!')