简易实时统计系统(能导出结果为html文件)

 附源代码:

# -*- coding: utf-8 -*-
import streamlit as st
import pandas as pd
import sqlite3
from jinja2 import Template
import os
import base64

# Initialize session state for questions and answers
if 'questions' not in st.session_state:
    st.session_state.questions = []

if 'answers' not in st.session_state:
    st.session_state.answers = {}

# Database initialization
def init_db():
    conn = sqlite3.connect('poll.db')
    c = conn.cursor()
    c.execute('''
        CREATE TABLE IF NOT EXISTS questions (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            question TEXT NOT NULL
        )
    ''')
    c.execute('''
        CREATE TABLE IF NOT EXISTS options (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            question_id INTEGER,
            option_text TEXT NOT NULL,
            votes INTEGER DEFAULT 0,
            FOREIGN KEY(question_id) REFERENCES questions(id)
        )
    ''')
    conn.commit()
    conn.close()

init_db()

# Save questions and options to the database
def save_to_db(question, options):
    conn = sqlite3.connect('poll.db')
    c = conn.cursor()
    
    c.execute("INSERT INTO questions (question) VALUES (?)", (question,))
    question_id = c.lastrowid
    
    for option in options:
        c.execute("INSERT INTO options (question_id, option_text) VALUES (?, ?)", (question_id, option))
    
    conn.commit()
    conn.close()

# Load questions and options from the database
def load_from_db():
    conn = sqlite3.connect('poll.db')
    c = conn.cursor()
    
    c.execute("SELECT * FROM questions")
    questions = c.fetchall()
    
    st.session_state.questions = [q[1] for q in questions]
    
    for q in questions:
        question_id = q[0]
        c.execute("SELECT option_text, votes FROM options WHERE question_id=?", (question_id,))
        options = c.fetchall()
        if q[1] not in st.session_state.answers:
            st.session_state.answers[q[1]] = {}
        for opt in options:
            st.session_state.answers[q[1]][opt[0]] = opt[1]
    
    conn.close()

# Delete a question from the database
def delete_from_db(question):
    conn = sqlite3.connect('poll.db')
    c = conn.cursor()
    
    c.execute("SELECT id FROM questions WHERE question=?", (question,))
    question_id = c.fetchone()[0]
    
    c.execute("DELETE FROM options WHERE question_id=?", (question_id,))
    c.execute("DELETE FROM questions WHERE id=?", (question_id,))
    
    conn.commit()
    conn.close()

# Add a question
def add_question():
    question = st.text_input("输入题目:", key="new_question")
    options = []
    for i in range(4):
        option = st.text_input(f"Option {i+1}:", key=f"option_{i}")
        options.append(option)
    
    if st.button("Add Question"):
        if question and all(options):
            st.session_state.questions.append(question)
            st.session_state.answers[question] = {opt: 0 for opt in options}
            save_to_db(question, options)
            st.success("题目添加成功!")
        else:
            st.warning("请填写问题和所有选项。")

# Display questions and allow voting
def display_questions():
    for idx, q in enumerate(st.session_state.questions):
        st.subheader(f"Question {idx + 1}: {q}")
        
        cols = st.columns(len(st.session_state.answers[q]))
        for i, (option, count) in enumerate(st.session_state.answers[q].items()):
            with cols[i]:
                new_count = st.number_input(f"{option}", min_value=0, value=count, step=1, key=f"count_{q}_{option}")
                st.session_state.answers[q][option] = new_count
        
        total_votes = sum(st.session_state.answers[q].values())
        if total_votes > 0:
            st.write("投票分布:")
            data = {
                "Option": list(st.session_state.answers[q].keys()),
                "Votes": list(st.session_state.answers[q].values()),
                "Percentage": [f"{(v / total_votes * 100):.2f}%" for v in st.session_state.answers[q].values()]
            }
            df = pd.DataFrame(data)
            st.table(df)

        # Export to HTML button
        if st.button(f"导出为HTML {idx + 1}", key=f"export_html_{idx}"):
            html_content = export_to_html(q, st.session_state.answers[q])
            b64 = base64.b64encode(html_content.encode()).decode()
            href = f'<a href="data:text/html;base64,{b64}" download="{q.replace(" ", "_")}.html">下载 HTML 文件</a>'
            st.markdown(href, unsafe_allow_html=True)

# Export data to HTML
def export_to_html(question, answers):
    template = Template("""
    <html>
    <head>
        <title>{{ question }}</title>
        <style>
            body {
                display: flex;
                justify-content: center;
                align-items: center;
                height: 100vh;
                margin: 0;
                font-family: Arial, sans-serif;
            }
            h1 {
                color: red;
                text-align: center;
            }
            table {
                width: 1000px;
                margin: auto;
                border-collapse: collapse;
            }
            th, td {
                border: 1px solid black;
                padding: 8px;
                text-align: center;
            }
        </style>
    </head>
    <body>
        
        <div style="text-align: center;">
        <h1>{{ question }}</h1>
            <table>
                <tr>
                    <th>选项</th>
                    <th>票数</th>
                    <th>百分比</th>
                </tr>
                {% for option, votes in answers.items() %}
                <tr>
                    <td>{{ option }}</td>
                    <td>{{ votes }}</td>
                    <td>{% if total_votes > 0 %}{{ "%.2f"|format((votes / total_votes * 100)) }}%{% else %}0.00%{% endif %}</td>
                </tr>
                {% endfor %}
            </table>
        </div>
    </body>
    </html>
    """)
    
    total_votes = sum(answers.values())
    html_content = template.render(question=question, answers=answers, total_votes=total_votes)

    return html_content

# Delete a question
def delete_question():
    if st.session_state.questions:
        question_index = st.selectbox("选择要删除的问题序号:", list(range(1, len(st.session_state.questions) + 1)))
        if st.button("Delete Question"):
            question_to_delete = st.session_state.questions[question_index - 1]
            delete_from_db(question_to_delete)
            st.session_state.questions.remove(question_to_delete)
            del st.session_state.answers[question_to_delete]
            st.success("问题删除成功!")
            load_from_db()  # Refresh the session state after deletion

# Main function
def main():
    st.title("实时统计系统1.0版")

    menu = ["Add Question", "View Statistics", "Delete Question"]
    choice = st.sidebar.selectbox("菜单", menu)

    load_from_db()

    if choice == "Add Question":
        add_question()
    elif choice == "View Statistics":
        display_questions()
    elif choice == "Delete Question":
        delete_question()

if __name__ == "__main__":
    main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值