James McCool commited on
Commit
d581c52
·
1 Parent(s): 42f907f

Refactor PDF export functionality in app.py to use ReportLab

Browse files

- Replaced pdfkit with ReportLab for PDF generation, enhancing the PDF export process.
- Implemented a new method to convert DataFrames directly to PDF using ReportLab's Table and styling features.
- Added error handling for PDF generation errors, improving user feedback.
- Updated requirements.txt to remove pdfkit and wkhtmltopdf, and include reportlab as a dependency.

Files changed (2) hide show
  1. app.py +45 -7
  2. requirements.txt +1 -2
app.py CHANGED
@@ -9,7 +9,10 @@ import numpy as np
9
  import pandas as pd
10
  import streamlit as st
11
  import gspread
12
- import pdfkit
 
 
 
13
 
14
  @st.cache_resource
15
  def init_conn():
@@ -99,14 +102,49 @@ def convert_df_to_csv(df):
99
  return df.to_csv().encode('utf-8')
100
 
101
  def convert_df_to_pdf(df):
102
- # Convert DataFrame to HTML first
103
- html = df.to_html()
104
- # Convert HTML to PDF using pdfkit
105
  try:
106
- pdf = pdfkit.from_string(html, False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  return pdf
108
- except ImportError:
109
- st.error("pdfkit is not installed. Please install pdfkit and wkhtmltopdf to enable PDF export.")
 
110
  return None
111
 
112
  matchups, overall_ms, team_frame, team_list, team_dict = init_baselines()
 
9
  import pandas as pd
10
  import streamlit as st
11
  import gspread
12
+ from reportlab.lib import colors
13
+ from reportlab.lib.pagesizes import letter, landscape
14
+ from reportlab.platypus import SimpleDocTemplate, Table, TableStyle
15
+ from io import BytesIO
16
 
17
  @st.cache_resource
18
  def init_conn():
 
102
  return df.to_csv().encode('utf-8')
103
 
104
  def convert_df_to_pdf(df):
 
 
 
105
  try:
106
+ # Create a buffer to receive PDF data
107
+ buffer = BytesIO()
108
+
109
+ # Create the PDF object using the buffer as its "file"
110
+ doc = SimpleDocTemplate(buffer, pagesize=landscape(letter))
111
+
112
+ # Convert DataFrame to a list of lists for the table
113
+ data = [df.columns.tolist()] + df.values.tolist()
114
+
115
+ # Create the table
116
+ table = Table(data)
117
+
118
+ # Add style to the table
119
+ style = TableStyle([
120
+ ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
121
+ ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
122
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
123
+ ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
124
+ ('FONTSIZE', (0, 0), (-1, 0), 10),
125
+ ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
126
+ ('BACKGROUND', (0, 1), (-1, -1), colors.white),
127
+ ('TEXTCOLOR', (0, 1), (-1, -1), colors.black),
128
+ ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
129
+ ('FONTSIZE', (0, 1), (-1, -1), 8),
130
+ ('GRID', (0, 0), (-1, -1), 1, colors.black),
131
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
132
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
133
+ ])
134
+ table.setStyle(style)
135
+
136
+ # Build the PDF
137
+ elements = [table]
138
+ doc.build(elements)
139
+
140
+ # Get the value of the BytesIO buffer
141
+ pdf = buffer.getvalue()
142
+ buffer.close()
143
+
144
  return pdf
145
+
146
+ except Exception as e:
147
+ st.error(f"Error generating PDF: {str(e)}")
148
  return None
149
 
150
  matchups, overall_ms, team_frame, team_list, team_dict = init_baselines()
requirements.txt CHANGED
@@ -2,9 +2,8 @@ streamlit
2
  gspread
3
  openpyxl
4
  matplotlib
5
- pdfkit
6
  pulp
7
  docker
8
  plotly
9
  scipy
10
- wkhtmltopdf
 
2
  gspread
3
  openpyxl
4
  matplotlib
 
5
  pulp
6
  docker
7
  plotly
8
  scipy
9
+ reportlab