Python Flask.py as service, html and jquery act as web page, include navigation, filter data via columns, pagination every 20 items

from flask import Flask, jsonify, request, send_from_directory
from flask_cors import CORS
import pandas as pd
import os
import re

app = Flask(__name__)
CORS(app)

# read CSV file
df=pd.read_csv('CSV_20251212212958732173.csv', encoding='utf-8')

#filter columns via keyword
def filter_columns(df, keyword):   
    filtered_cols = [col for col in df.columns if keyword in col]    
    return filtered_cols

@app.route('/')
def index():
    """provide html file"""
    return send_from_directory('.', 'index_2.html')

@app.route('/api/data')
def get_data():
    """API return data via type"""
    try:       

        # retrieve parameters        
        data_type = request.args.get('type', 'all')  
        page = int(request.args.get('page', 0))     
        page_size = 20                               

        #filter by type 
        if data_type == 'Name':
            columns = filter_columns(df, 'Name')
        elif data_type == 'Title':
            columns = filter_columns(df, 'Title')
        elif data_type == 'Topic':
            columns = filter_columns(df, 'Topic')
        elif data_type == 'Content':
            columns = filter_columns(df, 'Content')
        else:
            columns = df.columns.tolist()

         
        if 'Id' not in columns and 'Id' in df.columns:
            columns.insert(0, 'Id')

        
        filtered_df = df[columns]

        # Calculate page
        total = len(filtered_df)
        start = page * page_size
        end = min(start + page_size, total)

        # remainder
        has_more = end < total

        if start < total:
            # retrieve current page data
            page_data = filtered_df.iloc[start:end]
            data = page_data.to_dict('records')
        else:
            data = []

        return jsonify({
            'success': True,
            'data': data,
            'columns': columns,
            'total': total,
            'page': page,
            'has_more': has_more,
            'type': data_type
        })

    except FileNotFoundError:
        return jsonify({
            'success': False,
            'message': 'Data file does not exist'
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'message': f'Load failed: {str(e)}'
        })

@app.route('/api/columns')
def get_columns_info():
    """Retrieve columns info"""
    try:
        # Statistic columns
        columns_info = {
            'total': len(df.columns),
            'Name': filter_columns(df, 'Name'),
            'Title': filter_columns(df, 'Title'),
            'Topic': filter_columns(df, 'Topic'),
            'Content': filter_columns(df, 'Content'),
            'all': df.columns.tolist()
        }

        return jsonify({
            'success': True,
            'data': columns_info
        })

    except Exception as e:
        return jsonify({
            'success': False,
            'message': str(e)
        })

if __name__ == '__main__':
    print("Data Server starting...")
    print("Access url: http://127.0.0.1:5000")
    print("Data Type: Name | Title | Topic | Content")
    print("Each page contains 10 rows")
    app.run(debug=True, port=5000)




 <!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Filter Columns</title>
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: "Microsoft YaHei", Arial, sans-serif;
            background: #f5f5f5;
            color: #333;
            font-size: 12px;
        }
        
        .app-container {
            display: flex;
            min-height: 100vh;
        }
        
        /* Navigation Bar */
        .sidebar {
            width: 220px;
            background: #2c3e50;
            color: white;
            padding: 20px 0;
        }
        
        .logo {
            padding: 0 20px 20px;
            border-bottom: 1px solid #34495e;
            margin-bottom: 20px;
        }
        
        .logo h1 {
            font-size: 18px;
            color: #ecf0f1;
        }
        
        .logo p {
            font-size: 11px;
            color: #bdc3c7;
            margin-top: 5px;
        }
        
        .nav-menu {
            list-style: none;
        }
        
        .nav-item {
            margin: 5px 10px;
        }
        
        .nav-link {
            display: block;
            padding: 12px 15px;
            color: #bdc3c7;
            text-decoration: none;
            border-radius: 3px;
            transition: all 0.3s;
            font-size: 13px;
        }
        
        .nav-link:hover {
            background: #34495e;
            color: white;
        }
        
        .nav-link.active {
            background: #3498db;
            color: white;
        }
        
        .nav-icon {
            margin-right: 10px;
            width: 20px;
            text-align: center;
        }
        
        /* main-content */
        .main-content {
            flex: 1;
            padding: 20px;
            overflow-x: auto;
        }
        
        .content-header {
            margin-bottom: 20px;
        }
        
        .content-header h2 {
            color: #2c3e50;
            margin-bottom: 10px;
            font-size: 20px;
        }
        
        .content-header p {
            color: #7f8c8d;
            font-size: 13px;
        }        
        
        .controls {
            background: white;
            padding: 15px;
            border-radius: 5px;
            margin-bottom: 15px;
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
            display: flex;
            align-items: center;
            gap: 10px;
        }
        
        button {
            padding: 8px 15px;
            background: #3498db;
            color: white;
            border: none;
            border-radius: 3px;
            cursor: pointer;
            font-size: 12px;
            transition: background 0.3s;
        }
        
        button:hover {
            background: #2980b9;
        }
        
        button:disabled {
            background: #bdc3c7;
            cursor: not-allowed;
        }
        
        .status {
            margin-left: auto;
            color: #7f8c8d;
            font-size: 12px;
        }
        
        #loading {
            color: #3498db;
            display: none;
            margin-left: 10px;
        }
        
        #error {
            color: #e74c3c;
            margin-top: 10px;
            display: none;
            background: #ffeaea;
            padding: 10px;
            border-radius: 3px;
            font-size: 12px;
        }
         
        .table-container {
            overflow-x: auto;
            background: white;
            border-radius: 5px;
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        }
        
        table {
            width: 100%;
            border-collapse: collapse;
            min-width: 800px;
        }
        
        th, td {
            border: 1px solid #ecf0f1;
            padding: 6px 8px;
            text-align: left;
            white-space: nowrap;
            min-width: 80px;
        }
        
        th {
            background: #2c3e50;
            color: white;
            font-weight: bold;
            position: sticky;
            top: 0;
            z-index: 10;
        }
        
        tr:nth-child(even) {
            background: #f8f9fa;
        }
        
        tr:hover {
            background: #e8f4f8;
        }
        
        .scroll-hint {
            color: #7f8c8d;
            font-size: 11px;
            text-align: center;
            padding: 5px;
            background: #f8f9fa;
            border-top: 1px solid #ecf0f1;
        }
         
        .data-page {
            display: none;
        }
        
        .data-page.active {
            display: block;
        }
        
        @media (max-width: 768px) {
            .app-container {
                flex-direction: column;
            }
            
            .sidebar {
                width: 100%;
                padding: 10px;
            }
            
            .controls {
                flex-direction: column;
                align-items: stretch;
            }
            
            .status {
                margin-left: 0;
                margin-top: 10px;
            }
        }
    </style>
</head>
<body>
    <div class="app-container">
        <!-- Navigation bar -->
        <div class="sidebar">
            <div class="logo">
                <h1>📊 Data Monitor</h1>
                <p>Data Classifier</p>
            </div>
            
            <ul class="nav-menu">
                <li class="nav-item">
                    <a href="#Name" class="nav-link active" data-type="Name">
                        <span class="nav-icon">🔩</span> Name
                    </a>
                </li>
                <li class="nav-item">
                    <a href="#Title" class="nav-link" data-type="Title">
                        <span class="nav-icon">📏</span> Title
                    </a>
                </li>
                <li class="nav-item">
                    <a href="#Topic" class="nav-link" data-type="Topic">
                        <span class="nav-icon">⚡</span> Topic
                    </a>
                </li>
                <li class="nav-item">
                    <a href="#Content" class="nav-link" data-type="Content">
                        <span class="nav-icon">🚀</span> Content
                    </a>
                </li>
                <li class="nav-item">
                    <a href="#all" class="nav-link" data-type="all">
                        <span class="nav-icon">📋</span> All
                    </a>
                </li>
            </ul>
        </div>
        
        <!-- main-content -->
        <div class="main-content">
            <!-- Name -->
            <div id="Name" class="data-page active">
                <div class="content-header">
                    <h2>🔩 Name</h2>
                    <p>Show all columns contain 'Name'</p>
                </div>
                
                <div class="controls">
                    <button class="load-btn">Load 20 rows</button>
                    <button class="reset-btn">Reset</button>
                    
                    <div class="status">
                        <span class="info">Ready to load...</span>
                        <span class="loading">Loading...</span>
                    </div>
                </div>
                
                <div class="error"></div>
                
                <div class="table-container">
                    <table>
                        <thead class="table-header">
                            <!-- Table Headers generate dynamically-->
                        </thead>
                        <tbody class="table-body">
                            <!-- Data generate dynamically -->
                        </tbody>
                    </table>
                    <div class="scroll-hint">← Left Right Scroll See All Columns →</div>
                </div>
            </div>
            
            <!-- Title -->
            <div id="Title" class="data-page">
                <div class="content-header">
                    <h2>📏 Title</h2>
                    <p>Show all columns contain 'Title'</p>
                </div>
                
                <div class="controls">
                    <button class="load-btn">Load 20 rows</button>
                    <button class="reset-btn">Reset</button>
                    
                    <div class="status">
                        <span class="info">Ready to load......</span>
                        <span class="loading">Loading...</span>
                    </div>
                </div>
                
                <div class="error"></div>
                
                <div class="table-container">
                    <table>
                        <thead class="table-header">
                            <!-- Table Headers generate dynamically-->
                        </thead>
                        <tbody class="table-body">
                            <!-- Data generate dynamically -->
                        </tbody>
                    </table>
                    <div class="scroll-hint">← Left Right Scroll See All Columns →</div>
                </div>
            </div>
            
            <!-- Topic -->
            <div id="Topic" class="data-page">
                <div class="content-header">
                    <h2>⚡ Topic</h2>
                    <p>Show all columns contain 'Topic'</p>
                </div>
                
                <div class="controls">
                    <button class="load-btn">Load 20 rows</button>
                    <button class="reset-btn">Reset</button>
                    
                    <div class="status">
                        <span class="info">Ready to load...</span>
                        <span class="loading">Loading...</span>
                    </div>
                </div>
                
                <div class="error"></div>
                
                <div class="table-container">
                    <table>
                        <thead class="table-header">
                            <!-- Table Headers generate dynamically-->
                        </thead>
                        <tbody class="table-body">
                            <!-- Data generate dynamically -->
                        </tbody>
                    </table>
                    <div class="scroll-hint">← Left Right Scroll See All Columns →</div>
                </div>
            </div>
            
            <!-- Content -->
            <div id="Content" class="data-page">
                <div class="content-header">
                    <h2>🚀 Content</h2>
                    <p>Show all columns contain 'Content'</p>
                </div>
                
                <div class="controls">
                    <button class="load-btn">Load 20 rows</button>
                    <button class="reset-btn">Reset</button>
                    
                    <div class="status">
                        <span class="info">Ready to load...</span>
                        <span class="loading">Loading...</span>
                    </div>
                </div>
                
                <div class="error"></div>
                
                <div class="table-container">
                    <table>
                        <thead class="table-header">
                            <!-- Table Headers generate dynamically-->
                        </thead>
                        <tbody class="table-body">
                            <!-- Data generate dynamically -->
                        </tbody>
                    </table>
                    <div class="scroll-hint">← Left Right Scroll See All Columns →</div>
                </div>
            </div>
            
            <!-- All Data -->
            <div id="all" class="data-page">
                <div class="content-header">
                    <h2>📋 All Data</h2>
                    <p>Show All Data</p>
                </div>
                
                <div class="controls">
                    <button class="load-btn">Load 20 rows</button>
                    <button class="reset-btn">Reset</button>
                    
                    <div class="status">
                        <span class="info">Ready to load...</span>
                        <span class="loading">Loading...</span>
                    </div>
                </div>
                
                <div class="error"></div>
                
                <div class="table-container">
                    <table>
                        <thead class="table-header">
                            <!-- Table Headers generate dynamically-->
                        </thead>
                        <tbody class="table-body">
                            <!-- Data generate dynamically -->
                        </tbody>
                    </table>
                    <div class="scroll-hint">← Left Right Scroll See All Columns →</div>
                </div>
            </div>
        </div>
    </div>

    <script>
        // All State
        let currentState = {
            Name: { page: 0, total: 0, columns: [] },
            Title: { page: 0, total: 0, columns: [] },
            Topic: { page: 0, total: 0, columns: [] },
            Content: { page: 0, total: 0, columns: [] },
            all: { page: 0, total: 0, columns: [] }
        };
        
        let currentType = 'Name';
        
        // Switch page
        function switchPage(type) {
            currentType = type;
            
            // Nav activate
            $('.nav-link').removeClass('active');
            $(`.nav-link[data-type="${type}"]`).addClass('active');
            
            // Switch content
            $('.data-page').removeClass('active');
            $(`#${type}`).addClass('active');
            
            // Load Data
            loadData();
        }
         
        function loadData() {
            const page = currentState[currentType].page;
            const container = $(`#${currentType}`);
            
            // show loading state
            container.find('.loading').show();
            container.find('.load-btn').prop('disabled', true);
            container.find('.error').hide();
            
            // send request
            $.ajax({
                url: '/api/data',
                type: 'GET',
                data: {
                    type: currentType,
                    page: page
                },
                success: function(response) {
                    if (response.success) {
                        // update state
                        currentState[currentType].total = response.total;
                        currentState[currentType].columns = response.columns;
                        
                        // render table
                        renderTable(container, response.data, response.columns);                        
                        
                        updateStatus(container, response);                        
                        
                        if (response.has_more) {
                            container.find('.load-btn').prop('disabled', false);
                            currentState[currentType].page++;
                        } else {
                            container.find('.load-btn').prop('disabled', true);
                            container.find('.load-btn').text('Last Page');
                        }
                    } else {
                        showError(container, response.message);
                    }
                },
                error: function(xhr, status, error) {
                    showError(container, 'Network Error: ' + error);
                },
                complete: function() {
                    container.find('.loading').hide();
                }
            });
        }        
         
        function renderTable(container, data, columns) {
            const header = container.find('.table-header');
            const body = container.find('.table-body');
            
            // Generate Headers
            let headerHtml = '<tr>';
            columns.forEach(col => {
                let displayName = col;
                if (col.length > 15) {
                    displayName = col.substring(0, 12) + '...';
                }
                headerHtml += `<th title="${col}">${displayName}</th>`;
            });
            headerHtml += '</tr>';
            header.html(headerHtml);
            
            // Generate rows
            let bodyHtml = '';
            data.forEach(row => {
                bodyHtml += '<tr>';
                columns.forEach(col => {
                    let value = row[col];
                    
                    // Format display
                    if (value === null || value === undefined) {
                        value = '-';
                    } else if (typeof value === 'number') {
                        // Format value
                        value = formatNumber(value);
                    }
                    
                    bodyHtml += `<td title="${col}: ${value}">${value}</td>`;
                });
                bodyHtml += '</tr>';
            });
            body.html(bodyHtml);
        }
        
        // Number format
        function formatNumber(num) {
            if (Number.isInteger(num)) {
                return num.toString();
            }
            
            const absNum = Math.abs(num);
            if (absNum >= 1000) {
                return num.toFixed(0);
            } else if (absNum >= 100) {
                return num.toFixed(1);
            } else if (absNum >= 1) {
                return num.toFixed(2);
            } else {
                return num.toFixed(4);
            }
        }
         
        function updateStatus(container, response) {
            const page = response.page;
            const total = response.total;
            const startIdx = page * 20 + 1;
            const endIdx = Math.min((page + 1) * 20, total);
            
            container.find('.info').text(`Show ${startIdx}-${endIdx}  / total ${total} rows`);
        }        
        
        function showError(container, message) {
            container.find('.error').text('Error: ' + message).show();
        }        
        
        function resetPage(type) {
            const container = $(`#${type}`);
             
            currentState[type] = { page: 0, total: 0, columns: [] };
             
            container.find('.table-header').empty();
            container.find('.table-body').empty();
             
            container.find('.load-btn').prop('disabled', false);
            container.find('.load-btn').text('Load 20 rows data');
             
            container.find('.info').text('ready to load data...');
            container.find('.error').hide();
            
            if (type === currentType) {
                loadData();
            }
        }
        
        // Loading finished
        $(document).ready(function() {
            // Click nav event
            $('.nav-link').click(function(e) {
                e.preventDefault();
                const type = $(this).data('type');
                switchPage(type);
            });
            
            // load button click
            $('.load-btn').click(function() {
                const type = $(this).closest('.data-page').attr('id');
                currentType = type;
                loadData();
            });
            
            // reset button click
            $('.reset-btn').click(function() {
                const type = $(this).closest('.data-page').attr('id');
                resetPage(type);
            });
            
            // Initialization
            loadData();
        });
    </script>
</body>
</html>

 

 

 

image

 

 

 

image

 

 

 

image

 

image

 

 

 

 

 

 

 

 

 

image

 

 

 

 

 

 

 

image

 

 

 

 

 

 

image

 

 

 

 

 

 

 

 

 

image

 

 

 

 

 

 

 

 

image

 

 

 

 

 

 

 

 

 

image

 

 

 

image

 

 

The whole data set contains columns

image

 

Id Name ISBN FName Author MName Content LName Summary SurName Title Title2 Title3 Title4 FTitle LTitle Topic Topic2 Topic3 Topic4 Content2 Content3 Content4 GiveName

image

 

 

 

 

And generated by

import uuid
import pandas as pd
import numpy as np
from datetime import datetime

#show all rows when print
pd.set_option('display.max_rows',None)
book_list=[]
arr=range(1,1000001)
for a in arr:
    book_list.append({
        'Id':a,
        'Name':f'Name_{a}',
        'ISBN':f'ISBN_{uuid.uuid4().hex}_{a}',
        'FName':f'FName_{a}',
        'Author':f'Author_{a}',
        'MName':f'Manem_{a}',
        'Content':f'Content_{a}',
        'LName':f'LName_{a}',
        'Summary':f'Summary_{a}',        
        'SurName':f'SurName_{a}',
        'Title':f'Title_{a}',
        'Title2':f'Title2_{a}',
        'Title3':f'Title3_{a}',
        'Title4':f'Title4_{a}',
        'FTitle':f'FTitle_{a}',
        'LTitle':f'LTitle_{a}',
        'Topic':f'Topic_{a}',
        'Topic2':f'Topic2_{a}',
        'Topic3':f'Topic3_{a}',
        'Topic4':f'Topic4_{a}',
        'Content2':f'Content2_{a}',
        'Content3':f'Content3_{a}',
        'Content4':f'Content4_{a}',
        'GiveName':f'GivenName_{a}'
    })

df=pd.DataFrame(book_list)
csv_file=f'CSV_{datetime.now().strftime('%Y%m%d%H%M%S%f')}.csv'
df.to_csv(csv_file,index=False,encoding='utf-8')
df=pd.read_csv(csv_file)

name_columns_list=list(col for col in df.columns if 'Name' in col)
if 'Id' in df.columns and 'Id' not in name_columns_list:
    name_columns_list.insert(0,'Id')

name_df=df[name_columns_list]
print('\nRow between 10 and 20 with name columns:')
print(name_df.iloc[9:19])

title_columns_list=list(col for col in df.columns if 'Title' in col)
if 'Id' in df.columns and 'Id' not in title_columns_list:
    title_columns_list.insert(0,'Id')

title_df=df[title_columns_list]
print(title_df.iloc[10:20])

 

posted @ 2025-12-12 22:27  FredGrit  阅读(2)  评论(0)    收藏  举报