# Directory Structure

```
├── .gitignore
├── img
│   ├── 1.png
│   ├── 2.png
│   └── 3.png
├── pom.xml
├── README.md
└── src
    └── main
        ├── java
        │   └── cn
        │       └── bigcoder
        │           └── mcp
        │               └── excel
        │                   └── mcpexcelserver
        │                       ├── dto
        │                       │   ├── BaseResponse.java
        │                       │   ├── ExcelReadRequest.java
        │                       │   ├── ExcelReadResponse.java
        │                       │   ├── ExcelWriteRequest.java
        │                       │   └── ExcelWriteResponse.java
        │                       ├── McpExcelServerApplication.java
        │                       └── servive
        │                           ├── ExcelReadService.java
        │                           └── ExcelWriteService.java
        └── resources
            ├── application.yml
            └── log4j2.xml
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
 1 | HELP.md
 2 | target/
 3 | !.mvn/wrapper/maven-wrapper.jar
 4 | !**/src/main/**/target/
 5 | !**/src/test/**/target/
 6 | 
 7 | ### STS ###
 8 | .apt_generated
 9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 | 
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 | 
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | !**/src/main/**/build/
30 | !**/src/test/**/build/
31 | 
32 | ### VS Code ###
33 | .vscode/
34 | 
```

--------------------------------------------------------------------------------
/src/main/java/cn/bigcoder/mcp/excel/mcpexcelserver/dto/ExcelReadRequest.java:
--------------------------------------------------------------------------------

```java
 1 | package cn.bigcoder.mcp.excel.mcpexcelserver.dto;
 2 | 
 3 | import lombok.Data;
 4 | import org.springframework.ai.tool.annotation.ToolParam;
 5 | 
 6 | /**
 7 |  * @author: bigcoder84
 8 |  * @date: 2025-04-12
 9 |  **/
10 | @Data
11 | public class ExcelReadRequest {
12 | 
13 |     @ToolParam(description = "文件绝对路径")
14 |     private String filePath;
15 | }
16 | 
```

--------------------------------------------------------------------------------
/src/main/java/cn/bigcoder/mcp/excel/mcpexcelserver/dto/ExcelReadResponse.java:
--------------------------------------------------------------------------------

```java
 1 | package cn.bigcoder.mcp.excel.mcpexcelserver.dto;
 2 | 
 3 | import java.util.List;
 4 | import java.util.Map;
 5 | import lombok.Builder;
 6 | import lombok.Data;
 7 | 
 8 | /**
 9 |  * @author: bigcoder84
10 |  * @date: 2025-04-12
11 |  **/
12 | @Builder
13 | @Data
14 | public class ExcelReadResponse {
15 | 
16 |     private List<Map<String, String>> dataList;
17 | }
18 | 
```

--------------------------------------------------------------------------------
/src/main/java/cn/bigcoder/mcp/excel/mcpexcelserver/dto/ExcelWriteResponse.java:
--------------------------------------------------------------------------------

```java
 1 | package cn.bigcoder.mcp.excel.mcpexcelserver.dto;
 2 | 
 3 | import lombok.Builder;
 4 | import lombok.Data;
 5 | import org.springframework.ai.tool.annotation.ToolParam;
 6 | 
 7 | /**
 8 |  * @author: bigcoder84
 9 |  * @date: 2025-04-12
10 |  **/
11 | @Builder
12 | @Data
13 | public class ExcelWriteResponse {
14 | 
15 |     @ToolParam(description = "文件绝对路径")
16 |     private String filePath;
17 | }
18 | 
```

--------------------------------------------------------------------------------
/src/main/resources/application.yml:
--------------------------------------------------------------------------------

```yaml
 1 | 
 2 | #server:
 3 | #  port: 8090
 4 | spring:
 5 |   application:
 6 |     name: mcp-excel-server
 7 |   main:
 8 |     web-application-type: none
 9 |     banner-mode: off
10 | 
11 |   # 默认 dev 环境
12 | #  profiles:
13 | #    active: dev
14 |   ai:
15 |     mcp:
16 |       server:
17 |         stdio: true # 启用stdio模式
18 |         name: mcp-server
19 |         version: 0.0.1
20 |         type: SYNC
21 | logging:
22 |   config: classpath:log4j2.xml
23 | 
```

--------------------------------------------------------------------------------
/src/main/java/cn/bigcoder/mcp/excel/mcpexcelserver/dto/BaseResponse.java:
--------------------------------------------------------------------------------

```java
 1 | package cn.bigcoder.mcp.excel.mcpexcelserver.dto;
 2 | 
 3 | import lombok.Data;
 4 | 
 5 | /**
 6 |  * @author: bigcoder84
 7 |  * @date: 2025-04-12
 8 |  **/
 9 | @Data
10 | public class BaseResponse<T> {
11 | 
12 |     private boolean success;
13 |     private String message;
14 |     private T data;
15 | 
16 |     private BaseResponse(boolean success, String message, T data) {
17 |         this.success = success;
18 |         this.message = message;
19 |         this.data = data;
20 |     }
21 | 
22 |     public static <T> BaseResponse<T> success(T data) {
23 |         return new BaseResponse<>(true, null, data);
24 |     }
25 | 
26 |     public static <T> BaseResponse<T> failed(String message) {
27 |         return new BaseResponse<>(false, message, null);
28 |     }
29 | }
30 | 
```

--------------------------------------------------------------------------------
/src/main/java/cn/bigcoder/mcp/excel/mcpexcelserver/McpExcelServerApplication.java:
--------------------------------------------------------------------------------

```java
 1 | package cn.bigcoder.mcp.excel.mcpexcelserver;
 2 | 
 3 | import cn.bigcoder.mcp.excel.mcpexcelserver.servive.ExcelReadService;
 4 | import cn.bigcoder.mcp.excel.mcpexcelserver.servive.ExcelWriteService;
 5 | import org.springframework.ai.tool.ToolCallbackProvider;
 6 | import org.springframework.ai.tool.method.MethodToolCallbackProvider;
 7 | import org.springframework.boot.SpringApplication;
 8 | import org.springframework.boot.autoconfigure.SpringBootApplication;
 9 | import org.springframework.context.annotation.Bean;
10 | 
11 | @SpringBootApplication
12 | public class McpExcelServerApplication {
13 | 
14 |     public static void main(String[] args) {
15 |         SpringApplication.run(McpExcelServerApplication.class, args);
16 |     }
17 | 
18 |     @Bean
19 |     public ToolCallbackProvider serverTools(ExcelWriteService excelWriteService,
20 |             ExcelReadService excelReadService) {
21 |         return MethodToolCallbackProvider
22 |                 .builder()
23 |                 .toolObjects(excelWriteService, excelReadService)
24 |                 .build();
25 |     }
26 | }
27 | 
```

--------------------------------------------------------------------------------
/src/main/resources/log4j2.xml:
--------------------------------------------------------------------------------

```
 1 | <?xml version="1.0" encoding="UTF-8" ?>
 2 | <configuration status="warn" monitorInterval="5">
 3 |     <properties>
 4 |         <property name="LOG_HOME" value="logs"/>
 5 |     </properties>
 6 |     <Appenders>
 7 |         <Console name="Console" target="SYSTEM_OUT">
 8 |             <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] [%-5level] %c{36}:%L --- %m%n"/>
 9 |         </Console>
10 |         <File name="File" fileName="${LOG_HOME}/file-log4j2.log">
11 |             <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss}] [%-5level] %l %c{36} - %m%n"/>
12 |         </File>
13 |         <RandomAccessFile name="AccessFile" fileName="${LOG_HOME}/info.log"
14 |                 immediateFlush="true">
15 |             <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss}] [%-5level] %l %c{36} - %m%n"/>
16 |         </RandomAccessFile>
17 |         <RollingFile name="RollingFile" fileName="${LOG_HOME}/log4j2.log"
18 |                 filePattern="logs/log4j2.%d{yyyy-MM-dd-HH-mm}.%i.log">
19 |             <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
20 |             <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss}] [%-5level] %l %c{36} - %msg%n"/>
21 |             <Policies>
22 |                 <OnStartupTriggeringPolicy/>
23 |                 <SizeBasedTriggeringPolicy size="10 KB"/>
24 |                 <TimeBasedTriggeringPolicy/>
25 |             </Policies>
26 |             <DefaultRolloverStrategy max="30"/>
27 |         </RollingFile>
28 |     </Appenders>
29 |     <Loggers>
30 |         <Root level="INFO">
31 |             <AppenderRef ref="Console"/>
32 |             <AppenderRef ref="File"/>
33 |             <AppenderRef ref="AccessFile"/>
34 |             <AppenderRef ref="RollingFile"/>
35 |         </Root>
36 |     </Loggers>
37 | </configuration>
```

--------------------------------------------------------------------------------
/src/main/java/cn/bigcoder/mcp/excel/mcpexcelserver/servive/ExcelReadService.java:
--------------------------------------------------------------------------------

```java
 1 | package cn.bigcoder.mcp.excel.mcpexcelserver.servive;
 2 | 
 3 | import cn.bigcoder.mcp.excel.mcpexcelserver.dto.BaseResponse;
 4 | import cn.bigcoder.mcp.excel.mcpexcelserver.dto.ExcelReadRequest;
 5 | import cn.bigcoder.mcp.excel.mcpexcelserver.dto.ExcelReadResponse;
 6 | import java.io.FileInputStream;
 7 | import java.io.IOException;
 8 | import java.util.ArrayList;
 9 | import java.util.HashMap;
10 | import java.util.List;
11 | import java.util.Map;
12 | import lombok.extern.slf4j.Slf4j;
13 | import org.apache.poi.hssf.usermodel.HSSFWorkbook;
14 | import org.apache.poi.ss.usermodel.Cell;
15 | import org.apache.poi.ss.usermodel.Row;
16 | import org.apache.poi.ss.usermodel.Sheet;
17 | import org.apache.poi.ss.usermodel.Workbook;
18 | import org.apache.poi.xssf.usermodel.XSSFWorkbook;
19 | import org.springframework.ai.tool.annotation.Tool;
20 | import org.springframework.stereotype.Service;
21 | 
22 | /**
23 |  * @author bigcoder84
24 |  * @Description
25 |  * @date 2025-03-26 11:35
26 |  */
27 | @Slf4j
28 | @Service
29 | public class ExcelReadService {
30 | 
31 | 
32 |     /**
33 |      * 根据搜索词搜索面试鸭面试题目
34 |      *
35 |      * @return 返回解析的JSON数据
36 |      */
37 |     @Tool(description = "用于读取本地excel中的内容，传入文件路径，返回JSON格式的数据")
38 |     public BaseResponse<ExcelReadResponse> readExcel(ExcelReadRequest request) {
39 |         log.info("开始读取Excel文件: {}", request);
40 |         String filePath = request.getFilePath();
41 |         try (FileInputStream fis = new FileInputStream(filePath)) {
42 |             Workbook workbook;
43 |             if (filePath.toLowerCase().endsWith(".xlsx")) {
44 |                 workbook = new XSSFWorkbook(fis);
45 |             } else if (filePath.toLowerCase().endsWith(".xls")) {
46 |                 workbook = new HSSFWorkbook(fis);
47 |             } else {
48 |                 throw new IllegalArgumentException("不支持的文件格式，仅支持.xlsx或.xls格式");
49 |             }
50 | 
51 |             List<Map<String, String>> result = new ArrayList<>();
52 |             Sheet sheet = workbook.getSheetAt(0);
53 |             Row headerRow = sheet.getRow(0);
54 |             int columnCount = headerRow.getLastCellNum();
55 | 
56 |             for (int i = 1; i <= sheet.getLastRowNum(); i++) {
57 |                 Row row = sheet.getRow(i);
58 |                 if (row == null) {
59 |                     continue;
60 |                 }
61 | 
62 |                 Map<String, String> rowData = new HashMap<>();
63 |                 for (int j = 0; j < columnCount; j++) {
64 |                     Cell headerCell = headerRow.getCell(j);
65 |                     Cell cell = row.getCell(j);
66 |                     String header = headerCell != null ? headerCell.toString() : "Column" + j;
67 |                     String value = cell != null ? cell.toString() : "";
68 |                     rowData.put(header, value);
69 |                 }
70 |                 result.add(rowData);
71 |             }
72 | 
73 |             workbook.close();
74 |             log.info("Excel文件读取完成，共处理{}行数据", result.size());
75 |             return BaseResponse.success(ExcelReadResponse.builder().dataList(result).build());
76 |         } catch (IOException e) {
77 |             log.error("读取Excel文件失败: {}", e.getMessage(), e);
78 |             return BaseResponse.failed("读取Excel文件失败,error:" + e.getMessage());
79 |         }
80 |     }
81 | }
```

--------------------------------------------------------------------------------
/src/main/java/cn/bigcoder/mcp/excel/mcpexcelserver/servive/ExcelWriteService.java:
--------------------------------------------------------------------------------

```java
 1 | package cn.bigcoder.mcp.excel.mcpexcelserver.servive;
 2 | 
 3 | import cn.bigcoder.mcp.excel.mcpexcelserver.dto.BaseResponse;
 4 | import cn.bigcoder.mcp.excel.mcpexcelserver.dto.ExcelWriteRequest;
 5 | import cn.bigcoder.mcp.excel.mcpexcelserver.dto.ExcelWriteResponse;
 6 | import java.io.FileOutputStream;
 7 | import lombok.extern.slf4j.Slf4j;
 8 | import org.apache.poi.ss.usermodel.*;
 9 | import org.apache.poi.xssf.usermodel.XSSFWorkbook;
10 | import org.springframework.ai.tool.annotation.Tool;
11 | import org.springframework.stereotype.Service;
12 | 
13 | import java.util.List;
14 | import java.util.Map;
15 | 
16 | /**
17 |  * @author bigcoder84
18 |  * @Description
19 |  * @date 2025-03-26 11:35
20 |  */
21 | @Slf4j
22 | @Service
23 | public class ExcelWriteService {
24 | 
25 |     /**
26 |      * 将JSON数据写入Excel文件
27 |      */
28 |     @Tool(description = "用于将JSON数据写入Excel文件，")
29 |     public BaseResponse<ExcelWriteResponse> writeToExcel(ExcelWriteRequest request) {
30 |         log.info("开始写入Excel文件: {}", request);
31 |         if (request.getDataList() == null || request.getDataList().isEmpty()) {
32 |             log.warn("没有数据需要写入Excel");
33 |             return BaseResponse.failed("没有数据需要写入的数据");
34 |         }
35 | 
36 |         try (Workbook workbook = new XSSFWorkbook()) {
37 |             Sheet sheet = workbook.createSheet("Sheet1");
38 | 
39 |             // 创建标题行样式
40 |             CellStyle headerStyle = workbook.createCellStyle();
41 |             headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
42 |             headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
43 |             headerStyle.setAlignment(HorizontalAlignment.CENTER);
44 |             //先设置表中的编码
45 |             Font headerFont = workbook.createFont();
46 |             headerFont.setBold(true);
47 |             headerStyle.setFont(headerFont);
48 | 
49 |             // 创建表头
50 |             List<String> headers = request.getHeaders();
51 |             Row headerRow = sheet.createRow(0);
52 |             int colNum = 0;
53 |             for (String header : headers) {
54 |                 Cell cell = headerRow.createCell(colNum++);
55 |                 cell.setCellValue(header);
56 |                 cell.setCellStyle(headerStyle);
57 |                 //先设置表中的编码
58 |             }
59 | 
60 |             // 写入数据
61 |             int rowNum = 1;
62 |             for (Map<String, String> rowData : request.getDataList()) {
63 |                 Row row = sheet.createRow(rowNum++);
64 |                 colNum = 0;
65 |                 for (String header : headers) {
66 |                     Cell cell = row.createCell(colNum++);
67 |                     Object value = rowData.get(header);
68 |                     if (value != null) {
69 |                         cell.setCellValue(value.toString());
70 |                     }
71 |                 }
72 |             }
73 | 
74 |             // 自动调整列宽
75 |             for (int i = 0; i < headers.size(); i++) {
76 |                 sheet.autoSizeColumn(i);
77 |             }
78 | 
79 |             // 设置 JVM 默认字符编码
80 |             System.setProperty("file.encoding", "UTF-8");
81 |             // 保存文件
82 |             try (FileOutputStream fileOut = new FileOutputStream(request.getFilePath())) {
83 |                 workbook.write(fileOut);
84 |             }
85 |             return BaseResponse.success(ExcelWriteResponse.builder().filePath(request.getFilePath()).build());
86 |         } catch (Exception e) {
87 |             log.error("写入Excel文件失败: {}", e.getMessage(), e);
88 |             return BaseResponse.failed("导出失败,error:" + e.getMessage());
89 |         }
90 |     }
91 | }
```

--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------

```
  1 | <?xml version="1.0" encoding="UTF-8"?>
  2 | <project xmlns="http://maven.apache.org/POM/4.0.0"
  3 |         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 |         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 |     <modelVersion>4.0.0</modelVersion>
  6 |     <groupId>cn.bigcoder.grpc.demo.mcpexcel</groupId>
  7 |     <artifactId>mcp-excel-server</artifactId>
  8 |     <version>0.0.1</version>
  9 |     <name>mcp-excel-server</name>
 10 |     <description>mcp-excel-server</description>
 11 |     <properties>
 12 |         <java.version>11</java.version>
 13 |         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 14 |         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 15 |         <spring-boot.version>3.2.5</spring-boot.version>
 16 |     </properties>
 17 |     <dependencies>
 18 |         <dependency>
 19 |             <groupId>org.springframework.boot</groupId>
 20 |             <artifactId>spring-boot-starter</artifactId>
 21 |         </dependency>
 22 | 
 23 |         <dependency>
 24 |             <groupId>org.springframework.boot</groupId>
 25 |             <artifactId>spring-boot-starter-test</artifactId>
 26 |             <scope>test</scope>
 27 |         </dependency>
 28 |         <dependency>
 29 |             <groupId>org.springframework.ai</groupId>
 30 |             <artifactId>spring-ai-mcp-server-spring-boot-starter</artifactId>
 31 |             <version>1.0.0-M6</version>
 32 |         </dependency>
 33 |         <dependency>
 34 |             <groupId>org.projectlombok</groupId>
 35 |             <artifactId>lombok</artifactId>
 36 |             <scope>provided</scope>
 37 |         </dependency>
 38 |         <!-- Apache POI for Excel processing -->
 39 |         <dependency>
 40 |             <groupId>org.apache.poi</groupId>
 41 |             <artifactId>poi</artifactId>
 42 |             <version>5.2.3</version>
 43 |         </dependency>
 44 |         <dependency>
 45 |             <groupId>org.apache.poi</groupId>
 46 |             <artifactId>poi-ooxml</artifactId>
 47 |             <version>5.2.3</version>
 48 |         </dependency>
 49 |         <dependency>
 50 |             <groupId>com.alibaba.fastjson2</groupId>
 51 |             <artifactId>fastjson2</artifactId>
 52 |             <version>2.0.43</version>
 53 |         </dependency>
 54 |         <!-- 使用 log4j2 的适配器进行绑定 -->
 55 |         <dependency>
 56 |             <groupId>org.apache.logging.log4j</groupId>
 57 |             <artifactId>log4j-slf4j-impl</artifactId>
 58 |             <version>2.19.0</version>
 59 |         </dependency>
 60 | 
 61 |         <!-- log4j2 日志门面 -->
 62 |         <dependency>
 63 |             <groupId>org.apache.logging.log4j</groupId>
 64 |             <artifactId>log4j-api</artifactId>
 65 |             <version>2.19.0</version>
 66 |         </dependency>
 67 | 
 68 |         <!-- log4j2 日志实面 -->
 69 |         <dependency>
 70 |             <groupId>org.apache.logging.log4j</groupId>
 71 |             <artifactId>log4j-core</artifactId>
 72 |             <version>2.19.0</version>
 73 |         </dependency>
 74 | 
 75 |     </dependencies>
 76 |     <dependencyManagement>
 77 |         <dependencies>
 78 |             <dependency>
 79 |                 <groupId>org.springframework.boot</groupId>
 80 |                 <artifactId>spring-boot-dependencies</artifactId>
 81 |                 <version>${spring-boot.version}</version>
 82 |                 <type>pom</type>
 83 |                 <scope>import</scope>
 84 |             </dependency>
 85 |         </dependencies>
 86 |     </dependencyManagement>
 87 | 
 88 |     <build>
 89 |         <plugins>
 90 |             <plugin>
 91 |                 <groupId>org.springframework.boot</groupId>
 92 |                 <artifactId>spring-boot-maven-plugin</artifactId>
 93 |                 <executions>
 94 |                     <execution>
 95 |                         <goals>
 96 |                             <goal>repackage</goal>
 97 |                         </goals>
 98 |                     </execution>
 99 |                 </executions>
100 |             </plugin>
101 |         </plugins>
102 |     </build>
103 | 
104 | </project>
105 | 
```

