Việc xuất dữ liệu lớn thường là một điểm nghẽn khi sử dụng FineReport. Bài viết này giới thiệu một phương pháp để giải quyết vấn đề này bằng cách tích hợp với một dịch vụ Python.
1. Thiết lập Dịch vụ Flask với Python
Đầu tiên, chúng ta cần triển khai một dịch vụ Flask bằng Python để nhận tham số và câu lệnh SQL từ FineReport. Mã ví dụ dưới đây sử dụng một câu lệnh SQL cố định, bạn có thể tùy chỉnh và mở rộng nó.
Mã Nguồn Dịch vụ Flask
from flask import Flask, request, jsonify, send_file
import pymysql
import pandas as pd
import threading
import os
import time
app = Flask(__name__)
# Cấu hình kết nối cơ sở dữ liệu
db_config = {
'host': 'your_db_host', # Thay thế bằng host DB của bạn
'user': 'your_db_user', # Thay thế bằng username DB của bạn
'password': 'your_db_password', # Thay thế bằng mật khẩu DB của bạn
'database': 'your_db_name' # Thay thế bằng tên DB của bạn
}
# Hàm kết nối tới cơ sở dữ liệu
def establish_db_connection():
return pymysql.connect(**db_config)
# Hàm xuất dữ liệu ra file CSV
def export_data_to_csv(sql_query, query_params, output_filename):
connection = establish_db_connection()
try:
with connection.cursor() as cursor:
# Thực thi truy vấn với tham số hóa để đảm bảo an toàn
cursor.execute(sql_query, query_params)
query_results = cursor.fetchall()
# Trả về None nếu không có kết quả
if not query_results:
return None
# Chuyển đổi kết quả sang DataFrame và ghi ra file CSV
df = pd.DataFrame(query_results, columns=[col[0] for col in cursor.description])
df.to_csv(output_filename, index=False, encoding='utf-8')
print(f"File CSV đã được tạo: {output_filename}")
return output_filename
finally:
connection.close()
# Hàm chạy tác vụ xuất file trong một tiến trình nền (thread)
def run_csv_generation(sql_query, query_params, output_filename):
export_data_to_csv(sql_query, query_params, output_filename)
# Endpoint để FineReport gọi tới.
# Ví dụ này sử dụng GET để đơn giản hóa, nhưng POST được khuyến nghị cho việc truyền tham số.
@app.route('/generate_report', methods=['GET'])
def trigger_report_generation():
# Lấy danh sách tham số từ query string của URL
input_params = request.args.getlist('params')
# Câu lệnh SQL mặc định, có thể thay đổi
base_sql = "SELECT * FROM sample_table"
# Tạo tên file duy nhất, ví dụ sử dụng timestamp
output_file = f'report_{int(time.time())}.csv'
# Khởi chạy tiến trình nền để tạo file CSV
processing_thread = threading.Thread(target=run_csv_generation, args=(base_sql, input_params, output_file))
processing_thread.start()
# Chờ tiến trình hoàn thành để đảm bảo file đã được tạo trước khi trả về
processing_thread.join()
# Kiểm tra sự tồn tại của file và trả về nếu thành công
if os.path.exists(output_file):
return send_file(output_file, as_attachment=True, mimetype='text/csv')
else:
return jsonify({'error': 'Failed to generate CSV file'}), 500
if __name__ == '__main__':
# Chạy ứng dụng Flask ở chế độ debug
app.run(debug=True)
2. Cấu hình Mẫu trên FineReport
Trên giao diện FineReport, bạn có thể cấu hình sự kiện nút bấm để gọi đến địa chỉ dịch vụ Flask đã thiết lập.
Lưu ý: Đoạn mã JavaScript này chỉ mang tính minh họa. Bạn có thể cần tối ưu hóa cách xử lý và hiển thị thông báo.
// Khi nút được nhấn, chuyển hướng trình duyệt tới địa chỉ dịch vụ Flask
window.location.href = "http://127.0.0.1:5000/generate_report";
// Hiển thị thông báo cho người dùng
FR.Msg.alert("Thông báo", "Dữ liệu đang được tải xuống, vui lòng đợi.");
3. Tệp Mẫu Minh Họa
Bạn có thể tải về tệp mẫu đính kèm để tham khảo.
(Tệp mẫu không được cung cấp trong bản dịch này)
4. Hướng Dẫn Sử Dụng Minh Họa
Do hạn chế về khả năng tải lên video, bạn đọc vui lòng tự mình thử nghiệm để hiểu rõ quy trình hoạt động.
Đây chỉ là một ý tưởng ban đầu để kiểm chứng, mã nguồn hiện tại còn nhiều điểm chưa hoàn thiện về độ ổn định và xử lý lỗi. Mong nhận được sự thông cảm và đóng góp ý kiến.