1. 完成檔案生成瀏覽器下載功能
This commit is contained in:
parent
0b18e4b8ab
commit
e329908d88
51
app.py
51
app.py
@ -1,8 +1,10 @@
|
||||
|
||||
import os
|
||||
import uuid
|
||||
from flask import Flask, render_template, request, send_file
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
import zipfile
|
||||
import io
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@ -24,6 +26,9 @@ def allowed_file(filename):
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
search_str = 'e771'
|
||||
|
||||
|
||||
return render_template("index.html")
|
||||
@app.route("/hello")
|
||||
def hello():
|
||||
@ -38,15 +43,42 @@ def upload_csv():
|
||||
if file.filename == '':
|
||||
return "No selected file", 400
|
||||
if file and allowed_file(file.filename):
|
||||
|
||||
unique_filename = str(uuid.uuid4()) + '.csv'
|
||||
csv_path = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename)
|
||||
uuid_str = str(uuid.uuid4())[:4]
|
||||
unique_filename = datetime.now().strftime("%Y%m%d_%H%M")+ '_' + uuid_str
|
||||
csv_path = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename+'.csv')
|
||||
file.save(csv_path)
|
||||
print(f"CSV file saved to {csv_path}")
|
||||
|
||||
|
||||
try:
|
||||
# 呼叫外部 Python 腳本來生成圖片
|
||||
subprocess.run([os.path.join(os.getcwd(), '.venv', 'Scripts', 'python'), 'generate_images.py', csv_path], check=True)
|
||||
subprocess.run([os.path.join(os.getcwd(), '.venv', 'Scripts', 'python'), 'generate_images.py', csv_path, unique_filename ], check=True)
|
||||
folder = app.config['GENERATED_IMAGES_FOLDER']
|
||||
matched_files = [f for f in os.listdir(folder) if uuid_str in f and f.endswith('.png')]
|
||||
print(f"Matched files: {matched_files}")
|
||||
|
||||
# 壓縮所有圖片到一個 zip
|
||||
zip_buffer = io.BytesIO()
|
||||
with zipfile.ZipFile(zip_buffer, 'w') as zip_file:
|
||||
for filename in matched_files:
|
||||
file_path = os.path.join(folder, filename)
|
||||
zip_file.write(file_path, arcname=filename)
|
||||
zip_buffer.seek(0)
|
||||
|
||||
# 刪除生成的圖片文件
|
||||
for filename in matched_files:
|
||||
file_path = os.path.join(folder, filename)
|
||||
os.remove(file_path)
|
||||
print(f"Deleted file: {file_path}")
|
||||
# 刪除 CSV 文件
|
||||
os.remove(csv_path)
|
||||
|
||||
|
||||
return send_file(
|
||||
zip_buffer,
|
||||
mimetype='application/zip',
|
||||
as_attachment=True,
|
||||
download_name=f'{unique_filename}_images.zip'
|
||||
)
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error generating images: {e}")
|
||||
return "Error generating images", 500
|
||||
@ -56,9 +88,8 @@ def upload_csv():
|
||||
except Exception as e:
|
||||
print(f"An unexpected error occurred: {e}")
|
||||
return "An unexpected error occurred", 500
|
||||
|
||||
|
||||
return "File uploaded successfully", 200
|
||||
|
||||
return "File uploaded successfully", 200
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@ -101,7 +101,7 @@ class ImageGenerator(QObject):
|
||||
self.stop()
|
||||
|
||||
@Slot()
|
||||
def generate_images(self, name_csv):
|
||||
def generate_images(self, name_csv, out_filename):
|
||||
# Placeholder for image generation logic
|
||||
print("Generating images...1")
|
||||
|
||||
@ -161,7 +161,7 @@ class ImageGenerator(QObject):
|
||||
|
||||
if i > 0 and i % 6 == 5:
|
||||
# Save the current scene to an image file every 5 items
|
||||
self.scene_to_image(self.scene, f"generated_image_{i//6}.png")
|
||||
self.scene_to_image(self.scene, f"{out_filename}_{i//6}.png")
|
||||
self.scene.clear()
|
||||
|
||||
print("Image generated and added to scene.")
|
||||
@ -177,17 +177,19 @@ if __name__ == "__main__":
|
||||
generator = ImageGenerator()
|
||||
generator.finished.connect(app.quit)
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
csv_file = "resource/sample.csv"
|
||||
out_filename = "generated_image"
|
||||
|
||||
if len(sys.argv) > 2:
|
||||
csv_file = sys.argv[1]
|
||||
print(f"Loading CSV file: {csv_file}")
|
||||
else:
|
||||
csv_file = "resource/sample.csv"
|
||||
print(f"No CSV file provided, using default: {csv_file}")
|
||||
out_filename = sys.argv[2]
|
||||
print(f"Loading CSV file: {csv_file}, Output filename: {out_filename}")
|
||||
|
||||
|
||||
sample_data = generator.read_csv(csv_file)
|
||||
print(f"Sample data loaded: {sample_data}")
|
||||
|
||||
generator.generate_images(sample_data)
|
||||
generator.generate_images(sample_data, out_filename)
|
||||
#generator.start()
|
||||
|
||||
# Run the application event loop
|
||||
|
||||
@ -3,13 +3,13 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CSV 轉圖片工具</title>
|
||||
<title>圓形鑰匙圈產生器</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>上傳 CSV 產生圖片</h1>
|
||||
<h1>圓形鑰匙圈產生器</h1>
|
||||
<form id="uploadForm" enctype="multipart/form-data">
|
||||
<input type="file" id="csvFile" name="csvFile" accept=".csv">
|
||||
<button type="submit">生成圖片</button>
|
||||
<!-- <button type="submit">生成圖片</button> -->
|
||||
</form>
|
||||
<div id="status"></div>
|
||||
<div id="downloadLink" style="display: none;">
|
||||
@ -36,8 +36,13 @@
|
||||
const formData = new FormData();
|
||||
formData.append('csvFile', fileInput.files[0]);
|
||||
|
||||
// 產生日期時間字串
|
||||
const now = new Date();
|
||||
const pad = n => n.toString().padStart(2, '0');
|
||||
const datetimeStr = `${now.getFullYear()}${pad(now.getMonth()+1)}${pad(now.getDate())}_${pad(now.getHours())}${pad(now.getMinutes())}`;
|
||||
|
||||
try {
|
||||
const response = await fetch('/upload_csv', { // 請確保後端路由與此匹配
|
||||
const response = await fetch('/upload_csv', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
@ -47,21 +52,26 @@
|
||||
throw new Error(`伺服器錯誤: ${response.status} - ${errorText}`);
|
||||
}
|
||||
|
||||
// 假設後端會返回圖片的 Blob 或直接是檔案的 URL
|
||||
// 如果後端直接返回圖片檔案,可以直接創建 Blob URL
|
||||
const imageBlob = await response.blob();
|
||||
const imageUrl = URL.createObjectURL(imageBlob);
|
||||
// 取得 zip blob 並建立下載連結
|
||||
const zipBlob = await response.blob();
|
||||
const zipUrl = URL.createObjectURL(zipBlob);
|
||||
|
||||
downloadAnchor.href = imageUrl;
|
||||
downloadAnchor.download = 'generated_image.png'; // 可以從後端獲取圖片名稱
|
||||
statusDiv.textContent = '圖片已成功生成!';
|
||||
downloadAnchor.href = zipUrl;
|
||||
downloadAnchor.download = `${datetimeStr}_圓形鑰匙產生器.zip`; // zip 檔名加上日期時間
|
||||
statusDiv.textContent = '圖片已成功生成!請點擊下方連結下載壓縮檔。';
|
||||
downloadLinkDiv.style.display = 'block';
|
||||
downloadAnchor.click(); // 自動觸發下載
|
||||
|
||||
} catch (error) {
|
||||
console.error('上傳或生成圖片失敗:', error);
|
||||
statusDiv.textContent = `生成圖片失敗: ${error.message || '未知錯誤'}`;
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('csvFile').addEventListener('change', function() {
|
||||
// 自動觸發表單提交
|
||||
document.getElementById('uploadForm').dispatchEvent(new Event('submit', {cancelable: true, bubbles: true}));
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user