前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >高质量编码--Python提取与合并Excel数据

高质量编码--Python提取与合并Excel数据

原创
作者头像
MiaoGIS
发布于 2023-03-06 09:33:40
发布于 2023-03-06 09:33:40
78900
代码可运行
举报
文章被收录于专栏:Python in AI-IOTPython in AI-IOT
运行总次数:0
代码可运行

假如遇到下面场景,不同项目使用不同的Excel文件跟踪进度,每周在该Excel新增一个sheet表。同时有多个这样的项目Excel文件。需要将所有项目文件中的信息提取合并到一个Excel文件中方便统计。

X项目
X项目
Y项目
Y项目

合并后的Excel

为方便使用,将此功能升级开发为一个Web页面

之所以可以提取各Excel sheet中的数据,前提示它们满足一定的模板格式,为方便找到格式错误,同时提供了模板格式检查的功能。

下面看一下后台代码实现:

excel_tools.py用作Excel指定信息提取以及合并

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# -*- coding:utf-8 -*-
import numpy as np
import pandas as pd
import os

import logging
import warnings
warnings.filterwarnings('ignore')
handler=logging.FileHandler('log.txt',mode='w')
logger=logging.getLogger(__name__)
logger.addHandler(handler)
def parse_week(filePath,sheet):
    _,fileNameExt=os.path.split(filePath)
    fileName,_=os.path.splitext(fileNameExt)
     

    df=pd.read_excel(filePath,sheet_name=sheet)

    row1=df.iloc[0,1:]
    name=row1[row1.notna()].values[0]

    
    columns1=df.iloc[:,0].str.strip()
    df.set_index(columns1,inplace=True)
    df.drop(columns=[df.columns[0]],inplace=True)
    
    dfTable=df.loc['本周任务':'下周计划']
    dfTable.reset_index(inplace=True)
    dfHead=dfTable.iloc[1]
    dfBody=dfTable.iloc[2:-1]
    dfBody.columns=dfHead
    
    dfBody.rename(columns=lambda x:str(x).strip(),inplace=True)
    #dfBody=dfBody.iloc[:,[5,-2]]
    dfBody=dfBody[['责任人','实际工作量(h)']]
    
    dfBody.dropna(inplace=True)
    dfBody=dfBody.assign(项目名称=name,文件来源=fileName,sheet=sheet)
    logger.setLevel(logging.DEBUG)
    logger.log(logging.DEBUG,f'{name}:{len(dfBody)}个人')
    return dfBody

def combine_week(dirPath,mode,customs):
     
    files=os.listdir(dirPath)

    sheets=[]
    sheetDict={}
    dfs=[]
    for file in files:
        filePath=os.path.join(dirPath,file)
        excel=pd.ExcelFile(filePath)
        sheetDict[file]=excel.sheet_names
        if mode=='first':
            sheetName=excel.sheet_names[0]
            sheets.append((file,sheetName))
        if mode=='last':
            sheetName=excel.sheet_names[-1]
            sheets.append((file,sheetName))
    if mode=='preview':
        pass
    if mode=='custom':
        
        customs=[(file,sheetName) for file,sheetName in customs if file in files]
            
        sheets=customs 
    errorDict={}
    print('sheets',sheets)
    for file,sheetName in sheets:
        errorDict.setdefault(file,{})
        try:
            filePath=os.path.join(dirPath,file)
            df0=parse_week(filePath,sheetName)
        except:
            print('error',file,sheetName)
            errorDict[file][sheetName]=True
            df0=None
        print(df0)
        dfs.append(df0)
     
    if dfs and not list(filter(lambda x:isinstance(x,None.__class__),dfs)):
        df=pd.concat(dfs)
    else:
        df=None
        
    print('sheetDict',sheetDict)
    return df,sheetDict,errorDict

if __name__=='__main__':
    
    pass

server.py使用tornado Web框架开发后台

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# -*- coding:utf-8 -*-
import tornado.web
import tornado.httpserver
from tornado.options import options,define
import tornado.ioloop
import os

import pandas as pd
import json
from excel_tools import *
define('port',default=8000,type=int)


class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        user=self.get_secure_cookie('user',None)
        return user
class listHandler(BaseHandler):
    @tornado.web.authenticated
    def get(self):
        print('list')
        self.render('list.html',username=self.current_user)
     
    def post(self):
        username=self.get_argument('username')
        data=Excel.filter(owner=username)
        data=list(data.dicts())
        print(username)
        self.write({'result':data})
      

class combineHandler(tornado.web.RequestHandler):
    def get(self):
        
        self.render('combine.html',df=None,result=None,errorDict=None,sheetDict=None)
    def post(self):
        df=None
        mode=self.get_argument('mode','first')
        sheetDict=None
        errorDict=None
        customs=None
        sheets=self.get_argument('sheets',None)
        print('sheets',sheets)
        if sheets:
            sheets=sheets.split(',')
            customs=[sheet.split('<>') for sheet in sheets]
            
            print(customs)
        files=self.request.files['file']
        dirPath='./static/combine/'+str(uuid.uuid1())
        os.mkdir(dirPath)
        
        for file in files:
            filename=file['filename']
         
            with open(dirPath+'/'+filename,'wb') as f:    
                f.write(file.body)
       
        df,sheetDict,errorDict=combine_week(dirPath,mode=mode,customs=customs)
        
        print(sheetDict)
        self.render('combine.html',df=df,errorDict=errorDict,sheetDict=sheetDict)

        
class App(tornado.web.Application):
    def __init__(self,*args,**kwargs):  
        tornado.web.Application.__init__(self,*args,**kwargs)

if __name__=='__main__':
    
    handlers=[('/combine',combineHandler),
                  ]
    template_path=os.path.join('.','template')
    static_path=os.path.join('.','static')
    app=App(handlers=handlers,template_path=template_path,
            static_path=static_path,login_url='/login',
            debug=True,cookie_secret='miao')
    options.parse_command_line()
    server=tornado.httpserver.HTTPServer(app)
    server.listen(options.port)
    tornado.ioloop.IOLoop().current().start()

前端页面combine.html代码如下:

代码语言:html
AI代码解释
复制
<!doctype html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta HTTP-EQUIV="pragma" CONTENT="no-cache">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>欢迎使用</title>

    <!-- Bootstrap -->
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <script src="/static/jquery/jquery.min.js"></script>
    <script src="/static/underscore/underscore.js"></script>
     <script src="/static/leg-tree.js"></script>
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>
    <link href="/static/bootstrap-table/dist/extensions/group-by-v2/bootstrap-table-group-by.css" rel="stylesheet">

    <link href="/static/bootstrap-table/dist/bootstrap-table.min.css" rel="stylesheet">
    <link href="/static/css/tree.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/tableexport.jquery.plugin@1.10.21/tableExport.min.js"></script>
    
    <script src="/static/bootstrap-table/dist/bootstrap-table.min.js"></script>
    
    <script src="/static/bootstrap-table/dist/extensions/group-by-v2/bootstrap-table-group-by.min.js"></script>
<script src="static/bootstrap-table/dist/extensions/export/bootstrap-table-export.js"></script>

    <script src="static/bootstrap-table/dist/locale/bootstrap-table-zh-CN.js"></script>
    <style>
        [type="submit"] {
            cursor: pointer;
        }
        
        
        
    </style>
     
</head>

<body>
 
   
    
        <div class="row">
    <div class="col-md-4">
        
    <form action="/combine" method="post" enctype="multipart/form-data">
 
  <div class="form-group">
    <label for="file">上传周报Excel</label>
    <input type="file"  id="file" name="file" required accept=".xlsx" multiple>
    <p class="help-block">可以同时选择多个Excel.</p>
  </div>
        <a href="/static/X项目周报.xlsx" >demo1下载</a>
        <a href="/static/Y项目周报.xlsx" >demo2下载</a>
         <a href="/static/Z项目周报.xlsx" >demo3下载</a>
          <a href="/static/A项目周报.xlsx" >错误格式demo下载</a>
  <div class="checkbox">
       <label class="radio-inline">
      <input type="radio" name="mode" id="preview" required value="preview"> 
      预览sheets</label>
        <label class="radio-inline">
      <input type="radio" name="mode" id="first" required value="first"> 
      使用第一个sheet</label>
      <label class="radio-inline">
        <input type="radio" name="mode"  id="last" required value="last"> 
      使用最后一个sheet</label>
          {% if sheetDict %}
           <label class="radio-inline" style="float: right;">
        <input type="radio" name="mode"   id="custom" required value="custom"> 
     自定义在右边树中选择需要合并的sheet</label>
   
              {% end %}    
     
  </div>
    <input type="hidden" name="sheets" id="sheets">
  <button type="submit" class="btn btn-primary">提交</button>
       <a href="/dashboard" class="btn btn-default">返回</a>
</form>
        {% if  errorDict %}
           <table class="table table-hover">
      <thead>
        <tr>
        
          <th>出错文件名称</th>
          <th>sheet名称</th>
       
        </tr>
      </thead>
      <tbody>
         {% set  fail=False %}
         {% for excel,sheet_dict in errorDict.items() %}
           {% for sheet,failure in sheet_dict.items() %}
          {% if  failure %}
          {% set  fail=True %}
        <tr>
        
          <td>{{excel}}</td>
          <td>{{sheet}}</td>
        
        </tr>
          {% end %}
           {% end %}
             {% end %}
      </tbody>
    </table>
        
          {% if not fail %}
          <h2>全部文件检查后,格式都正确</h2>
         {% end %}
            {% end %}
         </div>
        <div class="col-md-4">
    
         {% if sheetDict %}
      
        <div class="tree">
              {% end %}
		</div>
         
      </div>
      <div class="col-md-4">
       
     {% if not isinstance(df,None.__class__)  %}
<table id="table" data-show-export="true" data-file-name="周报合并"
  data-group-by="true"
  data-group-by-field="项目名称"
  >
  <thead>
    <tr>
      
      
 
        <th data-field="项目名称">项目名称</th>
        <th data-field="责任人">责任人</th>
      <th data-field="实际工作量(h)">实际工作量(h)</th>
          <th data-field="文件来源">文件来源</th>
      <th data-field="sheet">sheet</th>
    </tr>
  </thead>
</table>
 
    <input type="hidden" value="{{df.to_json(orient='records')}}" id="result">
     
     {% end %}
    {% import json %}
    {% if sheetDict %}
         <input type="hidden" value="{{json.dumps(sheetDict)}}" id="sheetDict"> 
    {% end %}
    
        </div>
     
     
   
  </div>
   
    
    <script src="/static/js/combine.js?v=2.0"></script>

</body>

</html>

页面JavaScript代码combine.js

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$(function () {
 
    
    
    if (!!$('#result')[0]) {
        var data = JSON.parse($('#result').val());
        $table = $('#table').bootstrapTable();
        
        $table.bootstrapTable('destroy').bootstrapTable({
        
        exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel', 'pdf'],
        exportOptions:{fileName:'合并周报'},
      })
        
   
        
        
        
        console.log(data);
        $table.bootstrapTable('load', data);
    }
    if (!!$('#sheetDict')[0]) {
        var sheetDict = JSON.parse($('#sheetDict').val());
        var treeData = _.map(sheetDict, (v, k) => {
            return {
                "name": k,
                "open": true,
                "ico": 'iconfont icon-yonghu',
                "cascade": true,
                "id": k,
                "checked": false,
                "children": _.map(v, value => {
                    return {
                        "name": value,
                        "open": true,
                        "ico": 'iconfont icon-yonghu',
                        "id": "---" + k + '<>' + value,
                        "checked": false
                    }
                })
            }
        })




        var arrs = []


        $(".tree").tree(treeData, arrs);

    }
 



    $('form').submit(function () {
        var sheets = _.filter($.getCheckedNodes(), x => x.startsWith('---')).map(x=>x.replace('---',''));
        console.log(sheets);
        $('#sheets').val(sheets.join(','));
    });

})

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
高质量编码--Excel POI点高德地图展示
Excel文件里记录着POI点信息(包含经纬度),这些记录也可以分类别保存在不同的sheet里。下面介绍如何根据sheet名称,自动把Excel里的点位信息在地图上分组点标记展示,地图展示选用高德地图API。
MiaoGIS
2023/01/18
9530
高质量编码--Excel POI点高德地图展示
前端开发---异步上传文件
有一个名为ajaxFileUpload的JQuery插件可以利用iframe来实现前端页面中异步上传文件。
MiaoGIS
2020/11/25
1.5K0
前端开发---异步上传文件
Python开发物联网数据分析平台---web框架
前端使用Bootstrap主题框架AdminLTE,后台使用python语言的tornado作为web框架。利用tornado的模板作为主要的动态页面生成方式,以及巧妙使用模板将json数据渲染到页面hidden元素的值,然后在js中直接用eval函数计算隐藏域的值来生成图表JavaScript插件所需的json数据来生成页面中相应的可视化图表。
MiaoGIS
2019/11/01
3.3K0
Python开发物联网数据分析平台---web框架
前端开发---使用bootstrap-table展示物联网数据
下面我们使用它开发页面来查询HJ 212协议传输过来的物联网传感器数据。基于前端的列排序,隐藏列,模糊搜索,列搜索,翻页都是对bootstrap-table简单的配置自动完成的。同时使用daterangepicker插件来选择时间范围,以及可以将查询出来的数据后台导出为Excel。
MiaoGIS
2020/11/26
1.5K0
前端开发---使用bootstrap-table展示物联网数据
高质量编码-在线Excel经纬度坐标系转换(前端开发)
前端html和js代码如下: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/cs
MiaoGIS
2021/07/15
7190
高质量编码-在线Excel经纬度坐标系转换(前端开发)
电子规范管理系统(2)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hotqin888/article/details/78008917
hotqin888
2018/09/11
1.1K0
电子规范管理系统(2)
Npoi导入导出Excel操作
    之前公司的一个物流商系统需要实现对订单的批量导入和导出,翻阅了一些资料,最后考虑使用NPOI实现这个需求。 在winform上面实现excel操作:http://www.cnblogs.com/CallmeYhz/p/4920293.html,NPOI的主页:http://npoi.codeplex.com/ 简介 NPOI 是 POI 项目的 .NET 版本。POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目, 使用 NPOI 你就可以在没有安装 Office 或者相应
用户1055830
2018/01/18
3.8K2
Npoi导入导出Excel操作
高质量编码--传感器数据同比
下面介绍其前端代码,先看html页面,使用boostrap作为样式和布局,引入了bootstrap-daterangepicker插件作为日期范围选择面板,引入select2插件作为下拉选择列表,引入moment作为时间格式化工具,引入echarts作为图表库:
MiaoGIS
2019/07/13
1.5K0
高质量编码--传感器数据同比
BootStrap-table的使用实现排序功能
BootStrap-table的使用实现排序功能 1.Bootstrap table 官网地址: http://bootstrap-table.wenzhixin.net.cn/zh-cn/documentation/ 2.下载相应的包后引入 <script src="./js/jquery-3.1.1.js"></script> <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="./bootstrap-3.3.
Dream城堡
2018/12/07
2.3K0
高质量编码--使用Pandas和Tornado构建高性能数据查询服务
大数情况下,数据保存在数据库中,使用SQL来从数据库中查询数据,但相对于直接从内存中取数据前者显得比较慢和笨重。下面介绍基于csv文件目录存储数据,使用Tornado来作为Web服务器,使用Pandas来高性能查询数据。
MiaoGIS
2019/07/12
1.5K0
高质量编码--使用Pandas和Tornado构建高性能数据查询服务
如何使用 Blazor 框架在前端浏览器中导入和导出 Excel
Blazor 是一个相对较新的框架,用于构建具有 .NET 强大功能的交互式客户端 Web UI。一个常见的用例是将现有的 Excel 文件导入 Blazor 应用程序,将电子表格数据呈现给用户,并且能够允许进行任何更改,最后将该数据导出回 Excel 文件或将其保存到数据库。
葡萄城控件
2023/10/11
5160
如何使用 Blazor 框架在前端浏览器中导入和导出 Excel
高质量编码-空气质量地图可视化
平时采用百度地图api来开发地图可视化,除了使用JavaScript API GL来开发地图可视化应用。也可以使用百度地图提供的MapVGL库来开发。使用JavaScript API GL时利用overlayer(label,marker,line,polygon等)来完成地图叠加层添加实现可视化,MapVGL由于采用了图层(layer)来群组管理叠加层,从而代码更简洁,开发更高效。
MiaoGIS
2022/01/07
6781
高质量编码-空气质量地图可视化
Bootstrap Table表格分页的使用及分页数据(Excel)导出
1:引入Bootstrap Table表格插件相关链接:这里直接拿来用就可以了,如果要下载到本地,可以自行去官网下载。
王小婷
2025/05/18
990
Bootstrap Table表格分页的使用及分页数据(Excel)导出
使用js-xlsx实现文件的导出
如题: 点击导出按钮,将页面的表格导出为excel格式 代码如下 使用js-xlsx进行导出 <!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>D
且陶陶
2023/04/12
3.5K0
使用js-xlsx实现文件的导出
EngineerCMS核心代码
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hotqin888/article/details/53367020
hotqin888
2018/09/11
1.4K0
前端基础:Boostrap
Bootstrap 是基于 HTML、CSS、JavaScript 的,它简洁灵活,使得 Web 开发更加快捷。
RendaZhang
2020/09/08
7.7K0
前端基础:Boostrap
基于maven+ssm的增删改查之添加员工实现
具体流程:我们在index.jsp在中,点击新增按钮,弹出添加员工信息模态框,同时,我们发送ajax请求从数据库中获取部门信息,新增时可以选择部门。输入完毕信息后,在发送请求完成保存操作。
西西嘛呦
2020/08/26
5580
基于maven+ssm的增删改查之添加员工实现
高质量编码-考勤记录日历可视化
工作就要上下班打卡,月末想要查看自己的考勤情况,考勤系统通常会记录各工号下的打卡记录。
MiaoGIS
2023/01/17
9600
高质量编码-考勤记录日历可视化
Vue.js 数据交换秘籍:导入与导出艺术
在构建交互式 Web 应用时,数据的导入与导出功能常常扮演着至关重要的角色。Vue.js,作为前端开发的佼佼者,不仅提供了强大的数据处理能力,还赋予了我们实现这些关键功能的灵活性。接下来,让我们一起探索如何在 Vue.js 的世界里,巧妙地进行数据的导入与导出,同时享受编程带来的乐趣。
Front_Yue
2024/08/14
2750
Vue.js 数据交换秘籍:导入与导出艺术
基于前端JS导出Excel文件(减轻服务端压力)
在很多OA或者CRM项目中,基本上都会涉及到Excel的导入导出的问题。 首先想到了POI和阿里的EasyExcel。 如果是小打小闹,导几千数据玩玩,服务器本身基本没什么压力,但如果高并发的情况下,且每次导出量不大服务器肯定是吃不消的(这里指的是没有对导出Excel服务器做优化或者负载处理)
Parker
2020/07/22
15.2K0
基于前端JS导出Excel文件(减轻服务端压力)
相关推荐
高质量编码--Excel POI点高德地图展示
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档