利用 tornado 实现表格文件预览

项目介绍

  本文将介绍笔者的一个项目,主要是利用tornado实现表格文件的预览,能够浏览的表格文件支持CSV以及Excel文件。预览的界面如下:

640?wx_fmt=png
文件浏览界面

  下面我们将看到这个功能是如何通过tornado来实现的。

代码

  该项目的代码结构如下图所示:

640?wx_fmt=png
项目的代码结构

  其中主要分为四个部分:

  • files

  • static

  • templates

  • py代码

其中,files文件夹为上传的表格文件的存放路径,static为前端的静态文件,后续将不用给出介绍,读者可以从该项目的github中下载(下载地址详见后面),templates文件夹主要存放HTML文件,而py文件用于后端控制。

  首先让我们看三个HTML文件,先是upload.html,其代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
    <link rel="shortcut icon" href="{{static_url('images/flower.ico')}}">
    <link rel="stylesheet" href="{{static_url('CSS/amazeui.min.css')}}">
    <script src="{{static_url('JS/amazeui.min.js')}}"></script>
    <script>
    $(function() {
        $('#doc-form-file').on('change', function() {
        var fileNames = '';
        $.each(this.files, function() {
            fileNames += '<span class="am-badge">' + this.name + '</span> ';
        });
        $('#file-list').html(fileNames);
        });
    });
    </script>
</head>
<body>

    <div align="center">
        <br><br>
        <h1>表格文件上传</h1>
    <form action='file' enctype="multipart/form-data" method='post'>
        <div class="am-form-group am-form-file">
            <button type="button" class="am-btn am-btn-primary am-btn-sm">选择要上传的文件</button>
            <input id="doc-form-file" type="file" name="file" multiple>
        </div>
        <div id="file-list"></div>
        <p>
            <button type="submit" class="am-btn am-btn-default">提交</button>
        </p>
    </form>
        <p><a href="/file_review"><button class="am-btn am-btn-danger">查看全部文件</button></a></p>

    </div>

</body>
</html>

这个是文件上传的网页,界面如下:

640?wx_fmt=png
文件上传页面

选择上传文件,完成上传后,则会显示如下界面:

640?wx_fmt=png
文件上传成功

接着是fileReview.html,其代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件浏览</title>
    <link rel="shortcut icon" href="{{static_url('images/flower.ico')}}">
    <link rel="stylesheet" href="{{static_url('CSS/bootstrap.min.css')}}">
    <link rel="stylesheet" href="{{static_url('CSS/amazeui.min.css')}}">
</head>
<body>

    <div align="center">
        <br><br>
    <h1>文件浏览</h1>
    <ul class="list-group" >
        {% for file in files %}
            {% if file.endswith('.csv') or file.endswith('.xls') or file.endswith('.xlsx') %}
            <li class="list-group-item"> <a href={{"/data?file="+file}}>{{ file }}</a></li>
            {% end %}
        {% end %}
    </ul>
    <a href="/file"><button class="btn btn-success" id="review">文件上传界面</button></a>
    </div>

</body>
</html>

该页面主要用于显示上传的表格文件,界面如下:

640?wx_fmt=png
查看全部文件

最后是dataReview.html,代码如下:

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>数据预览</title>
    <link rel="shortcut icon" href="{{static_url('images/flower.ico')}}">
    <link rel="stylesheet" href="{{static_url('CSS/table.css')}}">
    <link rel="stylesheet" href="{{static_url('CSS/bootstrap.min.css')}}">
</head>

<body>

    <br><br>
    <div align="center">
    <div >

    <table class="table table-striped table-bordered table-condensed table-responsive">
        <thead id="index">
            <tr>
                {% for title in data[0] %}
                <th>{{ title }}</th>
                {% end %}
            </tr>
        </thead>
        <tbody id="body">
            {% for line in data[1:] %}
            <tr>
                {% for cell in line %}
                <td>{{ cell }}</td>
                {% end %}
            </tr>
            {% end %}
        </tbody>
    </table>
    </div>
        <a href="/file"><button class="btn btn-warning" id="review">文件上传界面</button></a>
    </div>

</body>
</html>

该界面主要用于显示表格文件中的数据,比如刚才上传成功的Excel文件,其中的数据如下:

640?wx_fmt=png
表格数据预览

  仅有HTML页面是不够的,我们还需要Python代码来控制网页的运行,这就是server.py,其中的代码如下:

# -*- coding: utf-8 -*-

import xlrd
import os.path
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options

#定义端口为12306
define("port", default=12306, help="run on the given port", type=int)

class UploadFileHandler(tornado.web.RequestHandler):
    # get函数
    def get(self):
        self.render('upload.html')

    # post函数
    def post(self):
        # 文件的存放路径
        upload_path = os.path.join(os.path.dirname(__file__), 'files')
        # 提取表单中‘name’为‘file’的文件元数据
        file_metas = self.request.files['file']
        for meta in file_metas:
            filename = meta['filename']
            filepath = os.path.join(upload_path, filename)
            # 有些文件需要已二进制的形式存储,实际中可以更改
            with open(filepath, 'wb') as up:
                up.write(meta['body'])
            self.write("<br><br>")
            self.write('<p>上传%s成功!</p>' % filename)
            self.write('<p><a href="/file_review"><button>查看全部文件</button></a></p>')

class FileReviewHandler(tornado.web.RequestHandler):
    def get(self):
        # 文件的存放路径
        upload_path = os.path.join(os.path.dirname(__file__), 'files')
        files = os.listdir(upload_path)
        for file in files:
            if os.path.isdir(file):
                files.remove(file)

        self.render('fileReview.html', files=files)

class DataReviewHandler(tornado.web.RequestHandler):

    def get(self):
        filename = self.get_argument('file')
        print(filename)
        # 文件的存放路径
        upload_path = os.path.join(os.path.dirname(__file__), 'files')
        file_path = os.path.join(upload_path, filename)

        if filename.endswith('.csv'):
            with open(file_path, "r") as f:
                data = f.readlines()
            data = [line.strip().split(',') for line in data]

        elif filename.endswith('.xls') or filename.endswith('.xlsx'):
            tables = xlrd.open_workbook(file_path)
            table = tables.sheets()[0] # 第一张表格
            nrows = table.nrows

            # 循环行列表数据
            data = []
            for i in range(nrows):
                data.append(table.row_values(i))

        else:
            data = []

        self.render('dataReview.html', data=data)

# 主函数
def main():

    # 开启tornado服务
    tornado.options.parse_command_line()
    # 定义app
    app = tornado.web.Application(
            handlers=[(r'/file', UploadFileHandler),
                      (r'/file_review', FileReviewHandler),
                      (r'/data', DataReviewHandler)
                      ],    # 网页路径控制
            template_path=os.path.join(os.path.dirname(__file__), "templates"), # 模板路径
            static_path=os.path.join(os.path.dirname(__file__), "static"),  # 配置静态文件路径
          )
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

main()

点击运行server.py文件,在浏览中输入“localhost:12306/file”就能看到刚才的文件上传的页面了。

使用

  笔者提供了以下三种方式供读者使用该项目:

  • 直接使用

  • github使用

  • docker使用

直接使用

  读者按照上面的讲解,自己写一个项目,拷贝static文件夹,然后点击运行server.py,在浏览中输入“localhost:12306/file”就能使用该程序来浏览上传的表格了。

github使用

  从该项目的github地址:https://github.com/percent4/csv_file_review中下载该项目,命令如下:

git init
git clone https://github.com/percent4/csv_file_review

然后安装必要的第三方模块:xlrd, tornado, 点击运行server.py,在浏览中输入“localhost:12306/file”就能使用该程序来浏览上传的表格了。

docker使用

  首先拉取docker镜像:

docker pull jclian91/dockertest:csv_file_review.2019.02.21.2312

然后运行该镜像:

docker run -p 12306:12306 -v $PWD/db:/root/csv_file_review/src/files -it c97f252cd6e8 bash

注意, -it后面为刚才拉取的docker镜像的ID,需要将ID替换为你刚拉取的镜像ID,运行端口为本机的12306,上传的表格数据存放在$PWD/db路径下。进入虚拟机后,运行server.py即可启动服务,

[root@fbb2c3fb6ce1 src]# ls
__init__.py  files  server.py  static  templates
[root@fbb2c3fb6ce1 src]# python server.py

在浏览中输入“localhost:12306/file”就能使用该程序来浏览上传的表格了。

总结

  关于本项目的介绍就到这儿了,感谢大家阅读~

640?wx_fmt=jpeg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Tornado实现了WebSocket。WebSocket是一种在Web浏览器和服务器之间进行全双工通信的协议。它通过使用单一的长连接,允许服务器主动向客户端发送消息,而不需要客户端发出请求。这种实时性的通信模式使得WebSocket非常适合于实时聊天应用程序、多人在线游戏和其他需要实时数据传输的应用场景。 在Tornado中,你可以使用WebSocketHandler类来实现WebSocket的功能。通过继承WebSocketHandler类并覆盖on_message方法,你可以定义当服务器接收到客户端的消息时的处理逻辑。你还可以使用write_message方法向客户端发送消息。 以下是一个简单的Tornado实现WebSocket的示例代码: ```python import tornado.websocket import tornado.web class WebSocketHandler(tornado.websocket.WebSocketHandler): def on_message(self, message): # 处理接收到的消息 pass def open(self): # WebSocket连接建立时的处理逻辑 pass def on_close(self): # WebSocket连接关闭时的处理逻辑 pass app = tornado.web.Application([ (r'/ws', WebSocketHandler), ]) if __name__ == '__main__': app.listen(8888) tornado.ioloop.IOLoop.current().start() ``` 在上述代码中,WebSocketHandler类定义了三个方法:on_message、open和on_close。on_message方法用于处理接收到的消息,open方法用于处理WebSocket连接建立时的逻辑,on_close方法用于处理WebSocket连接关闭时的逻辑。你可以根据自己的需求来实现这些方法。 通过将WebSocketHandler类与一个URL pattern进行映射,你可以将WebSocket功能添加到你的Tornado应用中。在上述示例中,WebSocket的URL是/ws。 希望这个回答能够帮助你理解Tornado如何实现WebSocket功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [如何使用Tornado实现WebSocket服务器?](https://blog.csdn.net/cumt951045/article/details/107766729)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值