html.Embed or html.Iframe not rendering local pdf in plotly DASH app

Viewed 2297

I am trying to display a pdf I read from a local path inside a DASH app. I tried using Embed and Iframe. However, none of them is displaying the pdf. Also, there is no error its just blank. Below is the code snippet.

import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import PyPDF2
import docx2txt

from jupyter_dash import JupyterDash

#external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = JupyterDash(__name__)

app.layout = html.Div([
    html.Button('Submit',id='submit'),
    html.Embed(src="<path to .pdf>",width="750",height="400",type="application/pdf"),
    html.Div(id='my-div')
])


@app.callback(
    Output(component_id='my-div', component_property='children'),
    [Input(component_id='submit', component_property='n_clicks')]
)
def update_output_div(n_clicks):
   
    if n_clicks:        
        
        my_text = docx2txt.process("<path to .doc>")
        return 'You\'ve entered "{}"'.format(my_text)

app.run_server("inline",port=8060)

I have added a submit button and reading a word file just to ensure the app itself is working fine.

I am running the below in Jupyter in Chrome.

It works fine if I display an online pdf or website url.

Any suggestions?

Thanks in advance.

2 Answers

In order to render the file in browser, open and decode the file first, like this:

 with open('<static/blabla/_pdf_name.pdf', 'rb') as pdf:
       pdf_data = base64.b64encode(pdf.read()).decode('utf-8')

And just add ObjectEl dash element to yours app:

app.layout = html.Div([
dash.html.ObjectEl(data='data:application/pdf;base64,'+ pdf_data,type='application/pdf') etc...

I guess this is way too late to help you, but may help others who also get stranded here. The method that worked for me I got from this post: https://community.plotly.com/t/displaying-a-pdf-file-on-plotly-dash-dashboard-in-python/33493/6

I may be mistaken, but it seems relevant, that the file to be served is in the assets folder. When using other locations it nests the original app in the iFrame for me. The element I use is this one. html.Iframe(src=os.path.join("assets", "pdf_name.pdf"))

I stumbled upon this one, because I am having issues switching between different pdfs that are displayed. Hope this helps future answer-seekers.

Related