Java生成格式化的Word統(tǒng)計(jì)報(bào)告
本教程將詳細(xì)介紹如何使用Java從數(shù)據(jù)庫(kù)查詢圖書數(shù)據(jù),并生成格式化的Word統(tǒng)計(jì)報(bào)告。我們將使用Spring Boot框架和Apache POI庫(kù)來(lái)實(shí)現(xiàn)這一功能。
一、項(xiàng)目結(jié)構(gòu)
src/main/java
├── com/example/libraryreport
│ ├── controller
│ │ └── ReportController.java
│ ├── service
│ │ └── BookReportService.java
│ ├── mapper
│ │ └── BookReportMapper.java
│ └── LibraryReportApplication.java
二、核心代碼實(shí)現(xiàn)
1. 控制器層
@RestController
@RequestMapping("/api/reports")
public class ReportController {
@Autowired
private BookReportService bookReportService;
@GetMapping("/books")
public ResponseEntity<String> generateBookReport() {
try {
String fileName = "圖書統(tǒng)計(jì)報(bào)告_" + System.currentTimeMillis() + ".docx";
String outputPath = "reports/" + fileName;
bookReportService.generateReport(outputPath);
return ResponseEntity.ok("報(bào)告生成成功: " + outputPath);
} catch (Exception e) {
return ResponseEntity.status(500)
.body("報(bào)告生成失敗: " + e.getMessage());
}
}
}
2. 數(shù)據(jù)訪問(wèn)層接口
public interface BookReportMapper {
// 獲取圖書總量
int selectTotalBookCount();
// 按分類統(tǒng)計(jì)圖書數(shù)量
List<Map<String, Object>> selectBooksByCategory();
// 獲取熱門圖書TOP10
List<Map<String, Object>> selectPopularBooks();
// 獲取借閱統(tǒng)計(jì)
List<Map<String, Object>> selectBorrowStats();
}
3. 服務(wù)層實(shí)現(xiàn)
@Service
public class BookReportService {
@Autowired
private BookReportMapper bookReportMapper;
public void generateReport(String outputPath) throws Exception {
// 創(chuàng)建Word文檔
XWPFDocument document = new XWPFDocument();
try {
// 添加報(bào)告標(biāo)題
addTitle(document, "圖書館圖書統(tǒng)計(jì)報(bào)告");
// 添加生成日期
addGenerationDate(document);
// 添加圖書總量統(tǒng)計(jì)
addTotalBookCount(document);
// 添加分類統(tǒng)計(jì)表格
addCategoryStatistics(document);
// 添加熱門圖書列表
addPopularBooks(document);
// 添加借閱統(tǒng)計(jì)
addBorrowStatistics(document);
// 保存文檔
saveDocument(document, outputPath);
} finally {
document.close();
}
}
// 創(chuàng)建報(bào)告主標(biāo)題,設(shè)置居中、加粗和大號(hào)字體
private void addTitle(XWPFDocument document, String titleText) {
XWPFParagraph title = document.createParagraph();
title.setAlignment(ParagraphAlignment.CENTER);
XWPFRun titleRun = title.createRun();
titleRun.setText(titleText);
titleRun.setBold(true);
titleRun.setFontSize(20);
titleRun.setFontFamily("宋體");
// 添加空行
document.createParagraph();
}
// 在右上角添加報(bào)告生成日期
private void addGenerationDate(XWPFDocument document) {
XWPFParagraph datePara = document.createParagraph();
datePara.setAlignment(ParagraphAlignment.RIGHT);
XWPFRun dateRun = datePara.createRun();
dateRun.setText("生成日期: " + LocalDate.now().toString());
dateRun.setFontSize(12);
dateRun.setFontFamily("宋體");
// 添加空行
document.createParagraph();
}
// 顯示圖書館藏書總量
private void addTotalBookCount(XWPFDocument document) {
int totalCount = bookReportMapper.selectTotalBookCount();
XWPFParagraph sectionTitle = createSectionTitle(document, "一、圖書總量統(tǒng)計(jì)");
XWPFParagraph content = document.createParagraph();
XWPFRun run = content.createRun();
run.setText(String.format("圖書館目前共有藏書: %s冊(cè)", formatNumber(totalCount)));
run.setFontSize(14);
run.setFontFamily("宋體");
// 添加空行
document.createParagraph();
}
// 創(chuàng)建分類統(tǒng)計(jì)表格,包括序號(hào)、分類名稱、數(shù)量和占比
private void addCategoryStatistics(XWPFDocument document) throws Exception {
// 創(chuàng)建章節(jié)標(biāo)題
XWPFParagraph sectionTitle = createSectionTitle(document, "二、圖書分類統(tǒng)計(jì)");
// 獲取分類數(shù)據(jù)
List<Map<String, Object>> categories = bookReportMapper.selectBooksByCategory();
int total = bookReportMapper.selectTotalBookCount();
// 創(chuàng)建表格
XWPFTable table = document.createTable(1, 4);
table.setWidth("100%");
// 設(shè)置表頭
setTableHeader(table, "序號(hào)", "圖書分類", "數(shù)量", "占比");
// 填充數(shù)據(jù)
int index = 1;
for (Map<String, Object> category : categories) {
XWPFTableRow row = table.createRow();
row.getCell(0).setText(String.valueOf(index++));
row.getCell(1).setText(category.get("categoryName").toString());
int count = Integer.parseInt(category.get("count").toString());
row.getCell(2).setText(formatNumber(count));
double percent = (count * 100.0) / total;
row.getCell(3).setText(String.format("%.1f%%", percent));
}
// 添加匯總行
XWPFTableRow footer = table.createRow();
footer.getCell(1).setText("總計(jì)");
footer.getCell(2).setText(formatNumber(total));
footer.getCell(3).setText("100%");
// 添加空行
document.createParagraph();
}
// 列出熱門圖書TOP10,前三名用藍(lán)色加粗顯示
private void addPopularBooks(XWPFDocument document) {
// 創(chuàng)建章節(jié)標(biāo)題
XWPFParagraph sectionTitle = createSectionTitle(document, "三、熱門圖書TOP10");
List<Map<String, Object>> popularBooks = bookReportMapper.selectPopularBooks();
for (int i = 0; i < popularBooks.size(); i++) {
Map<String, Object> book = popularBooks.get(i);
XWPFParagraph item = document.createParagraph();
item.setIndentationLeft(200);
XWPFRun run = item.createRun();
run.setText(String.format("%d. 《%s》 - %s (借閱量: %s次)",
i + 1,
book.get("title"),
book.get("author"),
formatNumber(Long.parseLong(book.get("borrowCount").toString()))
);
run.setFontSize(12);
run.setFontFamily("宋體");
// 突出顯示前三名
if (i < 3) {
run.setBold(true);
run.setColor("0000FF");
}
}
// 添加空行
document.createParagraph();
}
// 創(chuàng)建借閱統(tǒng)計(jì)表格,顯示每月借閱量和同比增長(zhǎng)率
private void addBorrowStatistics(XWPFDocument document) {
// 創(chuàng)建章節(jié)標(biāo)題
XWPFParagraph sectionTitle = createSectionTitle(document, "四、借閱統(tǒng)計(jì)");
List<Map<String, Object>> borrowStats = bookReportMapper.selectBorrowStats();
// 創(chuàng)建表格
XWPFTable table = document.createTable(1, 3);
table.setWidth("100%");
// 設(shè)置表頭
setTableHeader(table, "月份", "借閱量", "同比增長(zhǎng)");
// 填充數(shù)據(jù)
for (Map<String, Object> stat : borrowStats) {
XWPFTableRow row = table.createRow();
row.getCell(0).setText(stat.get("month").toString());
row.getCell(1).setText(formatNumber(Long.parseLong(stat.get("count").toString())));
// 計(jì)算同比增長(zhǎng)
if (stat.containsKey("growthRate")) {
double growth = Double.parseDouble(stat.get("growthRate").toString());
row.getCell(2).setText(String.format("%.1f%%", growth * 100));
// 設(shè)置顏色:增長(zhǎng)為紅色,下降為綠色
XWPFRun growthRun = row.getCell(2).getParagraphs().get(0).getRuns().get(0);
if (growth > 0) {
growthRun.setColor("FF0000");
} else if (growth < 0) {
growthRun.setColor("00FF00");
}
} else {
row.getCell(2).setText("N/A");
}
}
}
// 輔助方法,創(chuàng)建統(tǒng)一的章節(jié)標(biāo)題格式
private XWPFParagraph createSectionTitle(XWPFDocument document, String title) {
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText(title);
run.setBold(true);
run.setFontSize(16);
run.setFontFamily("宋體");
return paragraph;
}
// 輔助方法,設(shè)置表格表頭樣式
private void setTableHeader(XWPFTable table, String... headers) {
XWPFTableRow headerRow = table.getRow(0);
for (int i = 0; i < headers.length; i++) {
XWPFRun run = headerRow.getCell(i).getParagraphs().get(0).createRun();
run.setText(headers[i]);
run.setBold(true);
run.setFontSize(12);
run.setFontFamily("宋體");
// 設(shè)置單元格背景色
headerRow.getCell(i).setColor("D3D3D3");
}
}
// 格式化數(shù)字顯示,添加千位分隔符
private String formatNumber(long number) {
return String.format("%,d", number);
}
// 保存Word文檔到指定路徑
private void saveDocument(XWPFDocument document, String outputPath) throws IOException {
// 確保目錄存在
File outputFile = new File(outputPath);
outputFile.getParentFile().mkdirs();
try (FileOutputStream out = new FileOutputStream(outputFile)) {
document.write(out);
}
}
}
四、運(yùn)行效果
文檔樣式細(xì)節(jié)
字體規(guī)范:
- 中文默認(rèn)使用"宋體",數(shù)字/英文自動(dòng)匹配
- 標(biāo)題層級(jí)分明(20號(hào)→16號(hào)→14號(hào)→12號(hào))
數(shù)字處理:
- 所有數(shù)量自動(dòng)添加千位分隔符(如
1,200) - 百分比保留1位小數(shù)(如
28.4%)
- 所有數(shù)量自動(dòng)添加千位分隔符(如
顏色標(biāo)記:
- 藍(lán)色:TOP3熱門圖書
- 紅色/綠色:借閱量增長(zhǎng)/下降
- 灰色:表格標(biāo)題背景
布局設(shè)計(jì):
- 章節(jié)間有適當(dāng)空行
- 表格寬度占滿頁(yè)面(100%)
- 列表項(xiàng)統(tǒng)一縮進(jìn)
數(shù)據(jù)完整性:
- 包含總量統(tǒng)計(jì)、分類占比、排行榜和趨勢(shì)分析
- 自動(dòng)計(jì)算百分比和增長(zhǎng)率
具體結(jié)果如下
+------------------------------------------+
| 圖書館圖書統(tǒng)計(jì)報(bào)告 |
| (大標(biāo)題) |
| |
| 生成日期:2023-05-20 (右上角小字) |
| |
| 一、圖書總量統(tǒng)計(jì) |
| 圖書館目前共有藏書:12,345冊(cè) |
| |
| 二、圖書分類統(tǒng)計(jì) |
| +----+------------+-------+-------+ |
| |序號(hào)| 圖書分類 | 數(shù)量 | 占比 | |
| +----+------------+-------+-------+ |
| |1 |計(jì)算機(jī)科學(xué) | 3,500 | 28.4% | |
| |2 |文學(xué) | 2,800 | 22.7% | |
| ... |
| | |總計(jì) |12,345 | 100% | |
| +----+------------+-------+-------+ |
| |
| 三、熱門圖書TOP10 |
| 1. 《Java編程思想》...(藍(lán)色加粗) |
| 2. 《三體》...(藍(lán)色加粗) |
| ... |
| |
| 四、借閱統(tǒng)計(jì) |
| +------------+--------+----------+ |
| | 月份 | 借閱量 | 同比增長(zhǎng) | |
| +------------+--------+----------+ |
| | 2023-01 | 1,200 | +15.2%↑ | |
| | 2023-02 | 980 | -8.3%↓ | |
| ... |
+-----------------------------------------+
五、總結(jié)
通過(guò)本教程,我們實(shí)現(xiàn)了:
- 使用Spring Boot構(gòu)建Web服務(wù)
- 通過(guò)MyBatis訪問(wèn)數(shù)據(jù)庫(kù)獲取統(tǒng)計(jì)信息
- 使用Apache POI生成格式化的Word文檔
- 實(shí)現(xiàn)表格、列表等復(fù)雜格式的輸出
這個(gè)方案可以輕松擴(kuò)展為其他類型的統(tǒng)計(jì)報(bào)告生成工具,只需修改SQL查詢和Word格式設(shè)置即可。
到此這篇關(guān)于Java生成格式化的Word統(tǒng)計(jì)報(bào)告的文章就介紹到這了,更多相關(guān)Java生成Word內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談MyBatis 如何執(zhí)行一條 SQL語(yǔ)句
Mybatis 是 Java 開發(fā)中比較常用的 ORM 框架。在日常工作中,我們都是直接通過(guò) Spring Boot 自動(dòng)配置,并直接使用,但是卻不知道 Mybatis 是如何執(zhí)行一條 SQL 語(yǔ)句的,下面就一起講解一下2021-05-05
關(guān)于@Transactional事務(wù)嵌套使用方式
Spring框架通過(guò)@Transactional注解來(lái)管理事務(wù),它可以作用于類和方法上,用于聲明事務(wù)的屬性,如傳播行為、隔離級(jí)別、超時(shí)時(shí)間等,Spring事務(wù)是基于AOP實(shí)現(xiàn)的,它在運(yùn)行時(shí)為加了@Transactional注解的方法或類創(chuàng)建代理2024-11-11
Java中while語(yǔ)句的簡(jiǎn)單知識(shí)及應(yīng)用
這篇文章主要給大家介紹了關(guān)于Java中while語(yǔ)句的簡(jiǎn)單知識(shí)及應(yīng)用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
Java實(shí)現(xiàn)的日期處理類完整實(shí)例
這篇文章主要介紹了Java實(shí)現(xiàn)的日期處理類,結(jié)合完整實(shí)例形式分析了Java針對(duì)日期的獲取、運(yùn)算、轉(zhuǎn)換等相關(guān)操作技巧,需要的朋友可以參考下2017-09-09
springboot利用aspose預(yù)覽office文件的實(shí)現(xiàn)過(guò)程
這篇文章主要給大家介紹了關(guān)于springboot利用aspose預(yù)覽office文件的相關(guān)資料,文中通過(guò)示例代碼以及圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考價(jià)值,需要的朋友可以參考下2021-06-06

