【问题标题】:Flask - Calling python function which takes input parameters on button OnClick eventFlask - 调用 python 函数,该函数在按钮 OnClick 事件上接受输入参数
【发布时间】:2021-09-20 16:05:26
【问题描述】:

我有一个带有下载按钮的 Flask 网络应用程序。当我单击按钮时,我想执行 python 方法,而不是 javascript 方法。这个 python 方法应该从网页中获取一些最近修改的 html 代码作为输入。

最准确的情况如下:要求用户填写一些文本中的空白,完成后点击下载按钮。当按钮被点击时,一个python函数render_pdf()被执行,它使用pdfkit库将html修改后的文本转换为pdf。

在最简单的版本中,我的项目具有以下结构:

 - static/sample.pdf
 - templates/index.html
 - main.py

这是我到目前为止的代码:

ma​​in.py

from flask import Flask, render_template
import pdfkit 

app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')
    
if __name__ == "__main__":
    app.run(debug=True)

index.html

<body>

    <p class="test">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Temporibus, beatae!
        <span contenteditable="true" class="badge alert-info name" data-placeholder="Enter your name" data-focused-advice="Start typing"></span><i class="fa fa-lg fa-plus-circle"></i>
        Lorem ipsum dolor sit, amet consectetur adipisicing elit. Perspiciatis, laboriosam?
    </p>

    <button onclick="render_pdf()"><a href="../static/sample.pdf" download="my_file">Download</a></button>
</body>

我要执行的python方法应该是这个,传入htmlstr作为输入:

import pdfkit

def render_pdf(htmlstr):
    pdfkit.from_string(htmlstr, './static/sample.pdf') 

我知道我可以通过执行document.getElementsByClassName("test")[0].innerHTML; 来使用 javascript 获得变量 htmlstr

我觉得我离那里很近,我已经检查了maybe a bit old but very similar questions,但我只是不知道如何将输入的 html 传递给 python 方法。我错过了什么?

【问题讨论】:

    标签: javascript python html ajax flask


    【解决方案1】:
    1. 定义运行脚本的 URL(路由)。
    2. 在您的 JavaScript 代码中,向第 1 步中定义的 URL 发出 HTTP 请求。

    很简单,我为你写了代码希望对你有帮助

    我还在github 做了一个要点。

    ma​​in.py

    from flask import Flask, render_template
    from flask import request
    import pdfkit
    
    
    ## ## ## ## ## ## ## ## ## ## ## ## 
    app = Flask(__name__)
    
    
    ## ## ## ## ## ## ## ## ## ## ## ## 
    # config wkhtmltopdf on my system
    path_wkhtmltopdf = r'C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe'
    config = pdfkit.configuration(wkhtmltopdf=path_wkhtmltopdf)
    
    
    # function of rendering
    def render_pdf(htmlstr):
        pdfkit.from_string(htmlstr, './static/sample.pdf', configuration=config) 
    
    
    ## ## ## ## ## ## ## ## ## ## ## ## 
    @app.route('/')
    def index():
        return render_template('index.html')
    
    
    @app.route('/update-file/', methods=['POST'])
    def convert_string_to_pdf():
        try:
            # geting the json request
            json = request.get_json()
            
            # call render_pdf function with new value
            render_pdf(json['htmlstr'])
            
            # '0' meaning no error
            return '0'
    
        except Exception as error:
            return str(error)
    
    
    ## ## ## ## ## ## ## ## ## ## ## ## 
    if __name__ == "__main__":
        app.run(debug=True)
    

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Convert HTML to PDF</title>
    </head>
    <body>
    
        <p class="test">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Temporibus, beatae!
            <span contenteditable="true" class="badge alert-info name" data-placeholder="Enter your name" data-focused-advice="Start typing"></span><i class="fa fa-lg fa-plus-circle"></i>
            Lorem ipsum dolor sit, amet consectetur adipisicing elit. Perspiciatis, laboriosam?
        </p>
    
        <br><br>
        <button onclick="commandServerToRender()">Convert to PDF</button>
    
        
        <br><br>
        <div id="downloadBox" hidden>
            <p style="color: green;"><b>File is ready to download</b></p>
            <a href="/static/sample.pdf" download="my_file">Download PDF File</a>
        </div>
    
        <div id="errorBox" hidden>
            <p style="color:red"><b>There was an error:</b></p>
            <p id="errorMessage" style="color:red"></p>
        </div>
    
    
        <script>
            function commandServerToRender() {
                test = document.getElementsByClassName("test")[0].innerHTML;
                downloadBox = document.getElementById('downloadBox');
                errorBox = document.getElementById('errorBox');
                errorMessage = document.getElementById('errorMessage');
    
                downloadBox.hidden = true;
                errorBox.hidden = true;
    
                // Sending data in JSON format using POST method
                //
                var xhr = new XMLHttpRequest();
                var url = "/update-file/";
    
                xhr.open("POST", url, true);
                xhr.setRequestHeader("Content-Type", "application/json");
    
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4 && xhr.status === 200) {
                        // if print 0 meaning that it was successfull
                        if (xhr.responseText == '0') {
                            downloadBox.hidden = false;
    
                        } else {
                            errorMessage.innerHTML = xhr.responseText;
                            errorBox.hidden = false;
    
                        }
                    }
                };
    
                var data = JSON.stringify({"htmlstr": test});
                xhr.send(data);
            }
        </script>
    </body>
    </html>
    

    编辑

    要设置编码(您在 cmets 中询问),您必须修改 render_pdf() 并将 &lt;meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 添加到 htmlstr,如下所示:

    (如果要添加整个html文件,则需要将此代码添加到html的&lt;head&gt;标签中)

    def render_pdf(htmlstr):
        pdfkit.from_string('<meta http-equiv="Content-type" content="text/html; charset=utf-8" />' + htmlstr, './static/sample.pdf', configuration=config) 
    

    【讨论】:

    • 完美运行!错误消息是一个很棒的额外内容。
    • 次要问题,如何设置字符编码,我在 中这样做: 但字符在pdf
    • 我也试过 xhr.setRequestHeader("Content-Type", "application/json;charset=iso-8859-1");但西班牙语字符仍然无法正确呈现
    • 我编辑了帖子并添加了编码,希望它能解决您的问题。
    猜你喜欢
    • 2017-07-24
    • 1970-01-01
    • 2015-08-02
    • 2015-04-27
    • 2015-09-03
    • 2021-11-03
    • 1970-01-01
    • 2016-10-03
    相关资源
    最近更新 更多