My python program with gradio that suppose can let the LLM generate excel file with the process as follow:
"import os
import time
import pandas as pd
import re
from io import StringIO
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer, BitsAndBytesConfig
import gradio as gr
from threading import Thread
from PyPDF2 import PdfReader  # Import PyPDF2 for PDF text extraction

MODEL_PATH = r"C:\Users\shermanhonsf\Desktop\Python\llama_develop\model\Llama3.2-1B-Instruct-HF-Model"  # Your model path

TITLE = """
Chat with Llama 3.2 1B
"""

PLACEHOLDER = """
Hi, I'm Llama. Ask me anything or upload a PDF to chat about its content.
"""

CSS = """
.duplicate-button {
    margin: auto !important;
    color: white !important;
    background: black !important;
    border-radius: 100vh !important;
}
h3 {
    text-align: center;
}
"""

# Set the device to "cuda" if you have a compatible GPU, otherwise "cpu"
device = "cuda" if torch.cuda.is_available() else "cpu"

# Configure quantization if needed (optional)
quantization_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_use_double_quant=True,
    bnb_4bit_quant_type="nf4"
)

# Load the tokenizer and model from the local directory
tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH)
model = AutoModelForCausalLM.from_pretrained(
    MODEL_PATH,
    torch_dtype=torch.bfloat16,
    device_map="auto",
    # quantization_config=quantization_config
)

# Move the model to the appropriate device
model.to(device)


def extract_pdf_text(pdf_path):
    """Extract all text from a PDF file."""
    try:
        reader = PdfReader(pdf_path)
        text = ""
        for page in reader.pages:
            text += page.extract_text()
        return text
    except Exception as e:
        return f"Error reading PDF: {e}"

# Function to extract CSV data from LLM output
def extract_csv_data(llm_output):
    # Define start and end markers for the CSV content
    start_marker = "#START_CSV"
    end_marker = "#END_CSV"
    
    # Locate the markers in the LLM output
    start_index = llm_output.find(start_marker)
    end_index = llm_output.find(end_marker)

    if start_index == -1 or end_index == -1:
        print("CSV markers not found in the output.")
        return None
    
    # Extract the CSV content between the markers
    csv_content = llm_output[start_index + len(start_marker):end_index].strip()
    return csv_content

# Function to convert the extracted CSV data to an Excel file
def convert_to_excel(llm_output, output_file='output.xlsx'):
    # Extract the CSV data from the LLM output
    csv_data = extract_csv_data(llm_output)
    
    # If no CSV data is found, return or handle the error
    if not csv_data:
        print("No CSV data found.")
        return "No CSV data to convert."

    # Convert the CSV data into a Pandas DataFrame
    try:
        df = pd.read_csv(StringIO(csv_data), sep=",")
        # Save the DataFrame to an Excel file
        df.to_excel(output_file, index=False)
        return f"Excel file saved as: {output_file}"
    except Exception as e:
        print(f"Error converting to Excel: {e}")
        return f"Error converting to Excel: {e}"

# Function to handle the "Convert to Excel" button click
def handle_convert_to_excel(llm_output):
    if not llm_output.strip():
        return "No output to convert. Please generate something first."
    
    # Call the conversion function and return the result
    return convert_to_excel(llm_output, output_file='llm_output.xlsx')

def stream_chat(message: str, history: list, system_prompt: str ="You are a helpful assistant. When asked to generate tabular data, please follow these rules:\n"
                    "1. Produce the specified data as a CSV table with a header row.\n"
                    "2. Ensure that fields in the CSV are separated by commas (',').\n"
                    "3. Enclose the CSV output with markers: \n"
                    "   - Begin with `#START_CSV`.\n"
                    "   - End with `#END_CSV`.\n",
                temperature: float = 0.8, max_new_tokens: int = 1024, top_p: float = 1.0, top_k: int = 20, penalty: float = 1.2, pdf_text: str = ""):
    print(f'message: {message}')
    print(f'history: {history}')
    print(f'system_prompt: {system_prompt}')
    print(f'temperature: {temperature}')
    print(f'max_new_tokens: {max_new_tokens}')
    print(f'top_p: {top_p}')
    print(f'top_k: {top_k}')
    print(f'penalty: {penalty}')
    print(f'Message: {message}')
    print(f'History: {history}')
    print(f'PDF Text: {pdf_text}')

    conversation = [
        {"role": "system", "content": system_prompt}
    ]

    # Add PDF content to the system prompt if provided
    if pdf_text.strip():
        pdf_summary = f"The user uploaded a PDF with the following content:\n{pdf_text[:2000]}...\n(This is a truncated summary if the text is too long.)"
        conversation.append({"role": "system", "content": pdf_summary})

    for prompt, answer in history:
        conversation.extend([
            {"role": "user", "content": prompt},
            {"role": "assistant", "content": answer},
        ])

    conversation.append({"role": "user", "content": message})

    # Prepare input IDs
    input_ids = tokenizer.apply_chat_template(
        conversation,
        # tokenize=True,
        add_generation_prompt=True,
        return_tensors="pt"
    ).to(device)

    streamer = TextIteratorStreamer(
        tokenizer,
        timeout=60.0,
        skip_prompt=True,
        skip_special_tokens=True
    )

    generate_kwargs = dict(
        input_ids=input_ids,
        max_new_tokens=max_new_tokens,
        do_sample=False if temperature == 0 else True,
        top_p=top_p,
        top_k=top_k,
        temperature=temperature,
        eos_token_id=[128001, 128008, 128009],
        streamer=streamer,
    )

    # Generate the response in a background thread
    with torch.no_grad():
        thread = Thread(target=model.generate, kwargs=generate_kwargs)
        thread.start()

    # Stream the response back to the user
    buffer = ""
    for new_text in streamer:
        buffer += new_text
        yield buffer

# Create the Gradio interface
chatbot = gr.Chatbot(height=600, show_copy_button=True, layout="panel", placeholder=PLACEHOLDER)

with gr.Blocks(css=CSS) as demo:
    gr.HTML(TITLE)
    
    # Add file uploader for PDF input
    pdf_file = gr.File(label="Upload PDF", type="filepath")
    pdf_textbox = gr.Textbox(label="Extracted PDF Text", placeholder="PDF content will appear here after upload.", lines=10, interactive=False)
    
    def process_pdf(file):
        if file is not None:
            pdf_text = extract_pdf_text(file.name)
            return pdf_text
        return "No PDF uploaded."

    pdf_file.change(process_pdf, inputs=pdf_file, outputs=pdf_textbox)
    
    # Chatbot interface
    chatbot = gr.Chatbot(height=600, show_copy_button=True, layout="panel", placeholder=PLACEHOLDER)
    llm_output_box = gr.Textbox(label="LLM Output", placeholder="Generated output will appear here.", lines=10, interactive=False)
    
    # Add the "Convert to Excel" button
    convert_button = gr.Button("Convert to Excel")
    excel_status_box = gr.Textbox(label="Excel Conversion Status", placeholder="Excel conversion status will appear here.", interactive=False)

    # Connect the button to the conversion function
    convert_button.click(handle_convert_to_excel, inputs=llm_output_box, outputs=excel_status_box)

    # Chat interface
    gr.ChatInterface(
        fn=stream_chat,
        chatbot=chatbot,
        fill_height=True,
        additional_inputs_accordion=gr.Accordion(
            label="⚙️ Parameters",
            open=False,
            render=False
        ),
        additional_inputs=[
            gr.Textbox(
                value="You are a helpful assistant. When asked to generate tabular data, please follow these rules:\n"
                    "1. Produce the specified data as a CSV table with a header row.\n"
                    "2. Ensure that fields in the CSV are separated by commas (',').\n"
                    "3. Enclose the CSV output with markers: \n"
                    "   - Begin with `#START_CSV`.\n"
                    "   - End with `#END_CSV`.\n",
                label="System Prompt",
                render=False,
            ),
            gr.Slider(
                minimum=0,
                maximum=1,
                step=0.1,
                value=0.8,
                label="Temperature",
                render=False,
            ),
            gr.Slider(
                minimum=128,
                maximum=8192,
                step=1,
                value=1024,
                label="Max new tokens",
                render=False,
            ),
            gr.Slider(
                minimum=0.0,
                maximum=1.0,
                step=0.1,
                value=1.0,
                label="Top_p",
                render=False,
            ),
            gr.Slider(
                minimum=1,
                maximum=20,
                step=1,
                value=20,
                label="Top_k",
                render=False,
            ),
            gr.Slider(
                minimum=0.0,
                maximum=2.0,
                step=0.1,
                value=1.2,
                label="Repetition penalty",
                render=False,
            ),
            pdf_textbox  # Pass the extracted PDF text as an additional input
        ],
        examples=[
            ["What are the main themes explored in the movie 'Dune', and how do they reflect contemporary issues?"],
            ["What are 3 practical techniques I can use to prioritize tasks more effectively in a busy work schedule?"],
            ["How does blockchain technology work, and what are its potential applications beyond cryptocurrencies?"],
            ["Show me a code snippet of a website's sticky header in CSS and JavaScript."],
        ],
        cache_examples=False,
    )

    # Update the LLM output box when the chatbot generates a response
    def update_llm_output(history):
        print(f"Current history: {history}")  # Add this line to see the history content
        if history:
            print("update_llm_output function test: Have history")
            return history[-1][1]  # Return the assistant's latest response
        print("update_llm_output function test: No history")
        return ""  # Handle the case where there is no history

    chatbot.change(update_llm_output, inputs=chatbot, outputs=llm_output_box)

if __name__ == "__main__":
    demo.launch(debug=True)
"
Make the download excel to the user's computer (i.e. the user browser), not download to my project. Show the added or modified code in the correct order relative to the original code.