在现代Web应用开发中,文件上传与数据处理是常见的功能需求。本文将全面解析一个基于Python Flask的Excel文件处理Web应用的开发过程,从文件上传功能实现到后端数据处理,再到常见问题解决,最后扩展到Java实现方案。通过本文,读者将掌握完整的文件处理Web应用开发流程。
文件上传功能的前端实现需要考虑用户体验和交互设计。以下是完整的HTML模板:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<!-- 样式部分保持不变 -->
</head>
<body>
<div class="container">
<h1>Excel文件处理工具</h1>
<form id="uploadForm" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="cookieInput">认证Cookie:</label>
<input type="text" id="cookieInput" name="cookie"
placeholder="请输入认证Cookie" required>
</div>
<!-- 文件上传区域 -->
<div class="upload-area" id="uploadArea">
<p>拖拽文件到此处或</p>
<label for="fileInput" class="btn">选择Excel文件</label>
<input type="file" id="fileInput" name="file"
accept=".xlsx,.xls" required>
<div class="file-info" id="fileInfo">未选择文件</div>
</div>
<button type="submit" class="btn" id="submitBtn" disabled>
开始处理
</button>
</form>
</div>
<script>
// JavaScript交互逻辑
document.getElementById('fileInput').addEventListener('change', function(e) {
const fileInfo = document.getElementById('fileInfo');
if(this.files.length > 0) {
fileInfo.textContent = `已选择: ${this.files[0].name}`;
document.getElementById('submitBtn').disabled = false;
}
});
// 表单提交处理
document.getElementById('uploadForm').addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
fetch('/process', {
method: 'POST',
body: formData
})
.then(response => response.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = '处理结果.xlsx';
a.click();
});
});
</script>
</body>
</html>from flask import Flask, request, send_file
import os
import pandas as pd
from datetime import datetime
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads'
@app.route('/process', methods=['POST'])
def process_file():
# 获取Cookie和文件
cookie = request.form.get('cookie')
file = request.files['file']
# 保存上传文件
filepath = os.path.join(app.config['UPLOAD_FOLDER'], 'temp.xlsx')
file.save(filepath)
# 处理Excel文件
result = process_excel(filepath, cookie)
# 返回处理结果
return send_file(result, as_attachment=True)
def process_excel(filepath, cookie):
# 读取Excel文件
df = pd.read_excel(filepath)
# 处理数据(示例)
df['处理时间'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 保存结果
output_path = 'result.xlsx'
df.to_excel(output_path, index=False)
return output_pathfrom datetime import datetime, timedelta
def get_today_timestamps():
"""获取当天0点和23:59:59的时间戳"""
today = datetime.now().date()
start = datetime.combine(today, datetime.min.time())
end = datetime.combine(today, datetime.max.time())
return int(start.timestamp()), int(end.timestamp())def has_orders(phone, cookie, start_time=None, end_time=None):
"""
检查指定手机号是否有订单
:param phone: 手机号
:param cookie: 认证cookie
:param start_time: 开始时间戳(可选)
:param end_time: 结束时间戳(可选)
:return: bool
"""
# 设置默认时间范围(最近30天)
if start_time is None:
start_time = int((datetime.now() - timedelta(days=30)).timestamp())
if end_time is None:
end_time = int(datetime.now().timestamp())
# 实际查询逻辑
try:
# 这里替换为实际的API调用
# response = query_order_api(phone, cookie, start_time, end_time)
# return response.has_orders
# 模拟返回
import random
return random.random() > 0.5
except Exception as e:
print(f"订单查询失败: {str(e)}")
return False@RestController
@RequestMapping("/api")
public class FileUploadController {
@PostMapping("/upload")
public ResponseEntity<Resource> handleFileUpload(
@RequestParam("file") MultipartFile file,
@RequestParam("cookie") String cookie) {
try {
// 1. 保存上传文件
Path tempFile = Files.createTempFile("upload-", ".xlsx");
file.transferTo(tempFile);
// 2. 处理Excel文件
Path resultFile = processExcel(tempFile, cookie);
// 3. 返回结果文件
Resource resource = new FileSystemResource(resultFile.toFile());
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"result.xlsx\"")
.body(resource);
} catch (Exception e) {
return ResponseEntity.status(500).build();
}
}
private Path processExcel(Path inputFile, String cookie) throws Exception {
// 使用Apache POI处理Excel
Workbook workbook = WorkbookFactory.create(inputFile.toFile());
Sheet sheet = workbook.getSheetAt(0);
// 示例处理:添加处理时间列
Row headerRow = sheet.getRow(0);
headerRow.createCell(headerRow.getLastCellNum())
.setCellValue("处理时间");
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss");
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
row.createCell(row.getLastCellNum())
.setCellValue(LocalDateTime.now().format(formatter));
}
// 保存结果
Path outputFile = Files.createTempFile("result-", ".xlsx");
try (FileOutputStream out = new FileOutputStream(outputFile.toFile())) {
workbook.write(out);
}
return outputFile;
}
}import java.time.*;
import java.time.format.DateTimeFormatter;
public class TimeUtils {
public static long getStartOfDayTimestamp() {
return LocalDate.now()
.atStartOfDay(ZoneId.systemDefault())
.toEpochSecond();
}
public static long getEndOfDayTimestamp() {
return LocalDate.now()
.atTime(LocalTime.MAX)
.atZone(ZoneId.systemDefault())
.toEpochSecond();
}
public static long getTimestamp(int year, int month, int day, int hour, int minute) {
return LocalDateTime.of(year, month, day, hour, minute)
.atZone(ZoneId.systemDefault())
.toEpochSecond();
}
}问题现象 | 可能原因 | 解决方案 |
|---|---|---|
无法选择文件 | 文件输入框被隐藏 | 检查CSS的display属性 |
上传后页面刷新 | 表单默认提交行为 | 阻止表单默认事件 |
大文件上传失败 | 服务器配置限制 | 调整最大文件大小限制 |
文件类型不正确 | 未验证文件类型 | 前端和后端双重验证 |
内存优化:
并发处理:
from concurrent.futures import ThreadPoolExecutor
def process_batch(phones, cookie):
with ThreadPoolExecutor(max_workers=4) as executor:
results = list(executor.map(
lambda p: has_orders(p, cookie),
phones
))
return results缓存机制:
@Cacheable(value = "orderCache", key = "#phone + #cookie")
public boolean checkOrders(String phone, String cookie) {
// 查询逻辑
}本文详细介绍了从文件上传到数据处理的完整流程,涵盖了前端实现、Python后端处理、Java实现方案以及常见问题解决。关键点包括:
未来可以进一步探索:
通过本文的指导,开发者可以快速构建健壮的文件处理Web应用,满足各种业务场景需求。