本文目录导读:

我来为您提供一个完整的Java报表系统案例,使用Spring Boot + MyBatis + Apache POI/JasperReports实现。
项目结构
src/main/java/com/example/report/
├── controller/
│ └── ReportController.java
├── service/
│ ├── ReportService.java
│ └── impl/
│ └── ReportServiceImpl.java
├── mapper/
│ ├── OrderMapper.java
│ └── UserMapper.java
├── entity/
│ ├── Order.java
│ └── User.java
├── utils/
│ └── ExcelExportUtil.java
└── ReportApplication.java
src/main/resources/
├── mapper/
│ ├── OrderMapper.xml
│ └── UserMapper.xml
└── templates/
└── report.jrxml
核心代码实现
实体类
// Order.java
package com.example.report.entity;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class Order {
private Long id;
private String orderNo;
private String customerName;
private BigDecimal amount;
private Integer status;
private Date createTime;
private String statusDesc;
}
// User.java
package com.example.report.entity;
import lombok.Data;
import java.util.Date;
@Data
public class User {
private Long id;
private String username;
private String email;
private String phone;
private Date createTime;
private Integer userStatus;
}
Mapper接口
// OrderMapper.java
package com.example.report.mapper;
import com.example.report.entity.Order;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@Mapper
public interface OrderMapper {
List<Order> getOrderReport(@Param("startDate") String startDate,
@Param("endDate") String endDate,
@Param("status") Integer status);
List<Map<String, Object>> getOrderStatistics(@Param("startDate") String startDate,
@Param("endDate") String endDate);
}
// UserMapper.java
package com.example.report.mapper;
import com.example.report.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface UserMapper {
List<User> getUserReport(@Param("startDate") String startDate,
@Param("endDate") String endDate);
}
Mapper XML
<!-- OrderMapper.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.report.mapper.OrderMapper">
<select id="getOrderReport" resultType="com.example.report.entity.Order">
SELECT
o.id,
o.order_no AS orderNo,
o.customer_name AS customerName,
o.amount,
o.status,
o.create_time AS createTime,
CASE o.status
WHEN 1 THEN '待付款'
WHEN 2 THEN '已付款'
WHEN 3 THEN '已完成'
WHEN 4 THEN '已取消'
ELSE '未知状态'
END AS statusDesc
FROM orders o
<where>
<if test="startDate != null and startDate != ''">
AND o.create_time >= #{startDate}
</if>
<if test="endDate != null and endDate != ''">
AND o.create_time <= #{endDate}
</if>
<if test="status != null">
AND o.status = #{status}
</if>
</where>
ORDER BY o.create_time DESC
</select>
<select id="getOrderStatistics" resultType="java.util.Map">
SELECT
DATE(create_time) AS date,
COUNT(*) AS orderCount,
COALESCE(SUM(amount), 0) AS totalAmount,
AVG(amount) AS avgAmount
FROM orders
<where>
<if test="startDate != null and startDate != ''">
AND create_time >= #{startDate}
</if>
<if test="endDate != null and endDate != ''">
AND create_time <= #{endDate}
</if>
</where>
GROUP BY DATE(create_time)
ORDER BY date DESC
</select>
</mapper>
<!-- UserMapper.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.report.mapper.UserMapper">
<select id="getUserReport" resultType="com.example.report.entity.User">
SELECT
u.id,
u.username,
u.email,
u.phone,
u.create_time AS createTime,
u.user_status AS userStatus
FROM users u
<where>
<if test="startDate != null and startDate != ''">
AND u.create_time >= #{startDate}
</if>
<if test="endDate != null and endDate != ''">
AND u.create_time <= #{endDate}
</if>
</where>
ORDER BY u.create_time DESC
</select>
</mapper>
Service层
// ReportService.java
package com.example.report.service;
import com.example.report.entity.Order;
import com.example.report.entity.User;
import java.util.List;
import java.util.Map;
public interface ReportService {
List<Order> getOrderReport(String startDate, String endDate, Integer status);
List<User> getUserReport(String startDate, String endDate);
List<Map<String, Object>> getOrderStatistics(String startDate, String endDate);
byte[] exportOrderReportExcel(String startDate, String endDate, Integer status);
byte[] exportUserReportExcel(String startDate, String endDate);
byte[] exportOrderReportPDF(String startDate, String endDate, Integer status);
}
// ReportServiceImpl.java
package com.example.report.service.impl;
import com.example.report.entity.Order;
import com.example.report.entity.User;
import com.example.report.mapper.OrderMapper;
import com.example.report.mapper.UserMapper;
import com.example.report.service.ReportService;
import com.example.report.utils.ExcelExportUtil;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class ReportServiceImpl implements ReportService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private UserMapper userMapper;
@Override
public List<Order> getOrderReport(String startDate, String endDate, Integer status) {
return orderMapper.getOrderReport(startDate, endDate, status);
}
@Override
public List<User> getUserReport(String startDate, String endDate) {
return userMapper.getUserReport(startDate, endDate);
}
@Override
public List<Map<String, Object>> getOrderStatistics(String startDate, String endDate) {
return orderMapper.getOrderStatistics(startDate, endDate);
}
@Override
public byte[] exportOrderReportExcel(String startDate, String endDate, Integer status) {
List<Order> orders = getOrderReport(startDate, endDate, status);
String[] headers = {"订单编号", "客户名称", "订单金额", "订单状态", "创建时间"};
String[] fields = {"orderNo", "customerName", "amount", "statusDesc", "createTime"};
return ExcelExportUtil.exportToExcel(headers, fields, orders);
}
@Override
public byte[] exportUserReportExcel(String startDate, String endDate) {
List<User> users = getUserReport(startDate, endDate);
String[] headers = {"用户名", "邮箱", "手机号", "注册时间", "状态"};
String[] fields = {"username", "email", "phone", "createTime", "userStatus"};
return ExcelExportUtil.exportToExcel(headers, fields, users);
}
@Override
public byte[] exportOrderReportPDF(String startDate, String endDate, Integer status) {
try {
List<Order> orders = getOrderReport(startDate, endDate, status);
// 加载报表模板
File file = ResourceUtils.getFile("classpath:templates/report.jrxml");
JasperReport jasperReport = JasperCompileManager.compileReport(file.getAbsolutePath());
// 准备数据
JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(orders);
Map<String, Object> parameters = new HashMap<>();
parameters.put("startDate", startDate);
parameters.put("endDate", endDate);
// 填充数据
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);
// 导出PDF
return JasperExportManager.exportReportToPdf(jasperPrint);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("导出PDF失败", e);
}
}
}
Excel导出工具类
// ExcelExportUtil.java
package com.example.report.utils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.util.ReflectionUtils;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
public class ExcelExportUtil {
public static <T> byte[] exportToExcel(String[] headers, String[] fields, List<T> dataList) {
try (Workbook workbook = new XSSFWorkbook();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
Sheet sheet = workbook.createSheet("报表数据");
// 创建表头样式
CellStyle headerStyle = workbook.createCellStyle();
Font headerFont = workbook.createFont();
headerFont.setBold(true);
headerFont.setColor(IndexedColors.WHITE.getIndex());
headerStyle.setFont(headerFont);
headerStyle.setFillForegroundColor(IndexedColors.BLUE.getIndex());
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
headerStyle.setAlignment(HorizontalAlignment.CENTER);
// 创建数据样式
CellStyle dataStyle = workbook.createCellStyle();
dataStyle.setAlignment(HorizontalAlignment.CENTER);
// 创建表头行
Row headerRow = sheet.createRow(0);
for (int i = 0; i < headers.length; i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(headers[i]);
cell.setCellStyle(headerStyle);
sheet.autoSizeColumn(i);
}
// 填充数据
int rowNum = 1;
for (T data : dataList) {
Row row = sheet.createRow(rowNum++);
for (int col = 0; col < fields.length; col++) {
Cell cell = row.createCell(col);
Object value = getFieldValue(data, fields[col]);
if (value != null) {
if (value instanceof Date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
cell.setCellValue(sdf.format(value));
} else {
cell.setCellValue(value.toString());
}
} else {
cell.setCellValue("");
}
cell.setCellStyle(dataStyle);
}
}
workbook.write(outputStream);
return outputStream.toByteArray();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("导出Excel失败", e);
}
}
private static Object getFieldValue(Object data, String fieldName) {
try {
Field field = data.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(data);
} catch (NoSuchFieldException | IllegalAccessException e) {
return null;
}
}
}
Controller
// ReportController.java
package com.example.report.controller;
import com.example.report.entity.Order;
import com.example.report.entity.User;
import com.example.report.service.ReportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/report")
public class ReportController {
@Autowired
private ReportService reportService;
@GetMapping("/orders")
public ResponseEntity<ApiResponse<List<Order>>> getOrderReport(
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate,
@RequestParam(required = false) Integer status) {
List<Order> orders = reportService.getOrderReport(startDate, endDate, status);
return ResponseEntity.ok(ApiResponse.success(orders));
}
@GetMapping("/users")
public ResponseEntity<ApiResponse<List<User>>> getUserReport(
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate) {
List<User> users = reportService.getUserReport(startDate, endDate);
return ResponseEntity.ok(ApiResponse.success(users));
}
@GetMapping("/statistics")
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getOrderStatistics(
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate) {
List<Map<String, Object>> statistics = reportService.getOrderStatistics(startDate, endDate);
return ResponseEntity.ok(ApiResponse.success(statistics));
}
@GetMapping("/export/excel/orders")
public ResponseEntity<byte[]> exportOrderExcel(
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate,
@RequestParam(required = false) Integer status) {
byte[] data = reportService.exportOrderReportExcel(startDate, endDate, status);
String filename = "order_report_" + System.currentTimeMillis() + ".xlsx";
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=" + filename)
.contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
.body(data);
}
@GetMapping("/export/excel/users")
public ResponseEntity<byte[]> exportUserExcel(
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate) {
byte[] data = reportService.exportUserReportExcel(startDate, endDate);
String filename = "user_report_" + System.currentTimeMillis() + ".xlsx";
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=" + filename)
.contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
.body(data);
}
@GetMapping("/export/pdf/orders")
public ResponseEntity<byte[]> exportOrderPDF(
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate,
@RequestParam(required = false) Integer status) {
byte[] data = reportService.exportOrderReportPDF(startDate, endDate, status);
String filename = "order_report_" + System.currentTimeMillis() + ".pdf";
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=" + filename)
.contentType(MediaType.APPLICATION_PDF)
.body(data);
}
// 通用响应类
public static class ApiResponse<T> {
private int code;
private String message;
private T data;
public static <T> ApiResponse<T> success(T data) {
ApiResponse<T> response = new ApiResponse<>();
response.setCode(200);
response.setMessage("success");
response.setData(data);
return response;
}
// getter and setter...
public int getCode() { return code; }
public void setCode(int code) { this.code = code; }
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
public T getData() { return data; }
public void setData(T data) { this.data = data; }
}
}
主启动类
// ReportApplication.java
package com.example.report;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.example.report.mapper")
public class ReportApplication {
public static void main(String[] args) {
SpringApplication.run(ReportApplication.class, args);
}
}
数据库表结构
-- 订单表
CREATE TABLE orders (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(50) NOT NULL UNIQUE,
customer_name VARCHAR(100) NOT NULL,
amount DECIMAL(10, 2) NOT NULL,
status TINYINT NOT NULL DEFAULT 1 COMMENT '1:待付款 2:已付款 3:已完成 4:已取消',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_create_time (create_time),
INDEX idx_status (status)
);
-- 用户表
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100),
phone VARCHAR(20),
user_status TINYINT DEFAULT 1 COMMENT '1:正常 0:禁用',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_create_time (create_time)
);
配置文件
# application.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/report_db?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: yourpassword
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.example.report.entity
configuration:
map-underscore-to-camel-case: true
server:
port: 8080
前端页面示例
<!-- report.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">报表系统</title>
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
<script>
// 获取订单报表
async function getOrderReport() {
const startDate = document.getElementById('startDate').value;
const endDate = document.getElementById('endDate').value;
const status = document.getElementById('status').value;
const params = new URLSearchParams();
if (startDate) params.append('startDate', startDate);
if (endDate) params.append('endDate', endDate);
if (status) params.append('status', status);
const response = await fetch(`/api/report/orders?${params}`);
const result = await response.json();
// 渲染表格
renderOrderTable(result.data);
}
// 导出Excel
function exportExcel() {
const startDate = document.getElementById('startDate').value;
const endDate = document.getElementById('endDate').value;
const status = document.getElementById('status').value;
let url = '/api/report/export/excel/orders?';
if (startDate) url += `startDate=${startDate}&`;
if (endDate) url += `endDate=${endDate}&`;
if (status) url += `status=${status}`;
window.open(url, '_blank');
}
// 导出PDF
function exportPDF() {
const startDate = document.getElementById('startDate').value;
const endDate = document.getElementById('endDate').value;
const status = document.getElementById('status').value;
let url = '/api/report/export/pdf/orders?';
if (startDate) url += `startDate=${startDate}&`;
if (endDate) url += `endDate=${endDate}&`;
if (status) url += `status=${status}`;
window.open(url, '_blank');
}
// 渲染订单统计图表
async function renderStatisticChart() {
const startDate = document.getElementById('startDate').value;
const endDate = document.getElementById('endDate').value;
const params = new URLSearchParams();
if (startDate) params.append('startDate', startDate);
if (endDate) params.append('endDate', endDate);
const response = await fetch(`/api/report/statistics?${params}`);
const result = await response.json();
// 使用ECharts渲染统计图
const chart = echarts.init(document.getElementById('statisticChart'));
const dates = result.data.map(item => item.date);
const amounts = result.data.map(item => item.totalAmount);
const option = {
title: { text: '订单金额统计' },
tooltip: {},
xAxis: { data: dates },
yAxis: {},
series: [{
name: '金额',
type: 'bar',
data: amounts
}]
};
chart.setOption(option);
}
</script>
</head>
<body>
<div>
<label>开始日期: <input type="date" id="startDate"></label>
<label>结束日期: <input type="date" id="endDate"></label>
<label>订单状态:
<select id="status">
<option value="">全部</option>
<option value="1">待付款</option>
<option value="2">已付款</option>
<option value="3">已完成</option>
<option value="4">已取消</option>
</select>
</label>
<button onclick="getOrderReport()">查询</button>
<button onclick="exportExcel()">导出Excel</button>
<button onclick="exportPDF()">导出PDF</button>
</div>
<div id="statisticChart" style="width: 600px; height: 400px;"></div>
<table id="orderTable">
<thead>
<tr>
<th>订单编号</th>
<th>客户名称</th>
<th>订单金额</th>
<th>订单状态</th>
<th>创建时间</th>
</tr>
</thead>
<tbody></tbody>
</table>
</body>
</html>
pom.xml依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
</parent>
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<!-- Apache POI for Excel -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.2</version>
</dependency>
<!-- JasperReports for PDF -->
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.20.0</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
这个完整的报表系统案例包含了:
- 数据查询:支持按日期范围、状态等多条件筛选
- Excel导出:使用Apache POI实现
- PDF导出:使用JasperReports实现
- 统计分析:支持订单金额统计、趋势分析
- 前端展示:提供查询界面和数据可视化
- RESTful API:提供标准化的数据接口
您可以根据实际需求调整报表类型、添加新的报表功能,或者扩展更多数据可视化方式。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播