根据文档要求写出详细的前后端代码
时间: 2024-11-12 21:41:20 浏览: 10
根据文档内容,可以将整个系统分为前端和后端两部分。以下是详细的前后端代码示例:
### 后端代码
#### 1. `ExcelHazardGenerator.java`
```java
package org.example;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
public class ExcelHazardGenerator {
public static void main(String[] args) throws IOException {
// 定义Excel文件路径
String file1Path = "attachments/file1.xlsx";
String file2Path = "attachments/file2.xlsx";
String file3Path = "attachments/file3.xlsx";
// 读取第一个Excel文件(项目和单价)
Workbook workbook1 = new XSSFWorkbook(new FileInputStream(file1Path));
Sheet sheet1 = workbook1.getSheetAt(0);
// 读取第二个Excel文件(危害因素名称)
Workbook workbook2 = new XSSFWorkbook(new FileInputStream(file2Path));
Sheet sheet2 = workbook2.getSheetAt(0);
// 读取第三个Excel文件(报价模板)
Workbook workbook3 = new XSSFWorkbook(new FileInputStream(file3Path));
Sheet sheet3 = workbook3.getSheetAt(0);
// 提取表格1中的项目名称和单价(从第3行开始,第一列是项目名称,第三列是单价)
List<String> projectNames = new ArrayList<>();
List<Double> prices = new ArrayList<>();
for (int i = 2; i <= sheet1.getLastRowNum(); i++) {
Row row = sheet1.getRow(i);
if (row != null) {
Cell projectCell = row.getCell(0);
Cell priceCell = row.getCell(2);
if (projectCell != null && priceCell != null && priceCell.getCellType() == CellType.NUMERIC) {
projectNames.add(projectCell.getStringCellValue().trim());
prices.add(priceCell.getNumericCellValue());
}
}
}
// 提取表格2中的危害因素名称(从第二行开始,第三列)
List<String> hazardNames = new ArrayList<>();
for (int i = 1; i <= sheet2.getLastRowNum(); i++) {
Row row = sheet2.getRow(i);
if (row != null) {
Cell hazardCell = row.getCell(2);
if (hazardCell != null && hazardCell.getCellType() == CellType.STRING) {
hazardNames.add(hazardCell.getStringCellValue().trim());
}
}
}
// 随机选择10到20个危害因素
Random random = new Random();
int numHazards = 10 + random.nextInt(11);
Set<Integer> chosenIndexes = new HashSet<>();
while (chosenIndexes.size() < numHazards) {
chosenIndexes.add(random.nextInt(projectNames.size()));
}
// 从表格3的第二行开始写入数据,并计算总价
double totalPrice = 0.0;
int rowIndex = 1;
for (int index : chosenIndexes) {
Row newRow = sheet3.createRow(rowIndex++);
String hazardName = hazardNames.get(random.nextInt(hazardNames.size()));
newRow.createCell(0).setCellValue(hazardName); // 危害因素名称
newRow.createCell(1).setCellValue(projectNames.get(index)); // 项目名称
double price = prices.get(index);
newRow.createCell(2).setCellValue(price); // 单价
newRow.createCell(4).setCellValue(price); // 单价
newRow.createCell(6).setCellValue(price); // 单价
newRow.createCell(3).setCellValue(projectNames.get(index));
newRow.createCell(5).setCellValue(projectNames.get(index));
totalPrice += price;
}
// 将总价写入到最后一行的第二列
Row totalRow = sheet3.createRow(rowIndex);
totalRow.createCell(1).setCellValue("岗前总价1");
totalRow.createCell(2).setCellValue(totalPrice);
totalRow.createCell(3).setCellValue("在岗总价2");
totalRow.createCell(4).setCellValue(totalPrice);
totalRow.createCell(5).setCellValue("离岗总价3");
totalRow.createCell(6).setCellValue(totalPrice);
// 保存修改后的Excel表格3
try (FileOutputStream fileOut = new FileOutputStream(file3Path)) {
workbook3.write(fileOut);
}
System.out.println("生成报表成功!");
workbook1.close();
workbook2.close();
workbook3.close();
}
public static void generatePrice(String excelFilePath) throws Exception {
// 这里可以调用main方法的逻辑,或者重新实现
main(null);
}
}
```
#### 2. `ExcelMerge.java`
```java
package org.example;
import org.apache.commons.text.similarity.LevenshteinDistance;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;
public class ExcelMerge {
private static final int SIMILARITY_THRESHOLD = 3;
private static final Pattern NUMERIC_PATTERN = Pattern.compile("\\d+");
public static void main(String[] args) throws IOException {
// 定义Excel文件路径
String file1Path = "attachments/file1.xlsx";
String file2Path = "attachments/file2.xlsx";
// 读取第一个Excel文件
Workbook workbook1 = new XSSFWorkbook(new FileInputStream(file1Path));
Sheet sheet1 = workbook1.getSheetAt(0);
// 读取第二个Excel文件
Workbook workbook2 = new XSSFWorkbook(new FileInputStream(file2Path));
Sheet sheet2 = workbook2.getSheetAt(0);
// 提取第一个表格的所有项目名称,并存入一个Set集合(避免重复)
Set<String> projectSet1 = new HashSet<>();
for (Row row : sheet1) {
Cell cell = row.getCell(0);
if (cell != null) {
projectSet1.add(cell.getStringCellValue().trim());
}
}
// 创建Levenshtein算法实例
LevenshteinDistance levenshtein = new LevenshteinDistance();
// 用来存储未找到匹配项目的唯一列表
Set<String> uniqueMissingProjects = new HashSet<>();
// 遍历第二个表格的每一行,查找第7列中的项目
for (Row row : sheet2) {
Cell cell = row.getCell(6);
if (cell != null) {
String projectNames = cell.getStringCellValue().trim();
String[] projectArray = projectNames.split(",");
for (String projectName2 : projectArray) {
projectName2 = projectName2.trim();
if (isNumeric(projectName2)) {
continue;
}
boolean isFound = false;
for (String projectName1 : projectSet1) {
int distance = levenshtein.apply(projectName2, projectName1);
if (distance <= SIMILARITY_THRESHOLD) {
System.out.println("Found similar project: " + projectName2 + " -> " + projectName1);
isFound = true;
break;
}
}
if (!isFound) {
uniqueMissingProjects.add(projectName2);
}
}
}
}
// 将uniqueMissingProjects中的唯一项目添加到sheet1中
int lastRowNum = sheet1.getLastRowNum();
Random random = new Random();
for (String missingProject : uniqueMissingProjects) {
Row newRow = sheet1.createRow(++lastRowNum);
newRow.createCell(0).setCellValue(missingProject);
int randomPrice = random.nextInt(100) + 1;
newRow.createCell(2).setCellValue(randomPrice);
}
// 保存修改后的第一个文件
try (FileOutputStream fileOut = new FileOutputStream(file1Path)) {
workbook1.write(fileOut);
}
System.out.println("完成!");
workbook1.close();
workbook2.close();
}
// 检查字符串是否为纯数字
private static boolean isNumeric(String str) {
return NUMERIC_PATTERN.matcher(str).matches();
}
}
```
### 前端代码
#### 1. HTML页面 (`index.html`)
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Generate Price</title>
</head>
<body>
<h1>生成报价</h1>
<form id="priceForm">
<label for="hazards">请输入危害因素(以逗号分隔):</label>
<input type="text" id="hazards" name="hazards" required>
<button type="submit">生成报价</button>
</form>
<div id="result"></div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
$('#priceForm').on('submit', function(event) {
event.preventDefault();
const hazards = $('#hazards').val();
$.ajax({
url: '/generate-price',
method: 'POST',
data: JSON.stringify({ hazards: hazards }),
contentType: 'application/json',
success: function(response) {
$('#result').html('<p>' + response.message + '</p>');
},
error: function(error) {
$('#result').html('<p>生成报价时出错:' + error.responseText + '</p>');
}
});
});
});
</script>
</body>
</html>
```
#### 2. Spring Boot Controller (`PriceController.java`)
```java
package org.example.controller;
import org.example.ExcelHazardGenerator;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PriceController {
@PostMapping("/generate-price")
public ResponseEntity<?> generatePrice(@RequestBody Map<String, String> requestBody) {
String hazards = requestBody.get("hazards");
try {
ExcelHazardGenerator.generatePrice(hazards);
return ResponseEntity.ok(Map.of("message", "报价生成成功!"));
} catch (Exception e) {
return ResponseEntity.badRequest().body(Map.of("message", "生成报价时出错:" + e.getMessage()));
}
}
}
```
### 总结
以上代码实现了以下功能:
1. **后端**:
- `ExcelHazardGenerator.java`:读取三个Excel文件,提取项目名称和单价,随机选择危害因素,并生成报价表。
- `ExcelMerge.java`:合并两个Excel文件中的项目名称,处理相似项目。
2. **前端**:
- `index.html`:提供一个简单的HTML表单,允许用户输入危害因素并提交请求。
- `PriceController.java`:Spring Boot控制器,接收前端请求,调用后端服务生成报价,并返回结果。
希望这些代码能满足您的需求。如果有任何问题或需要进一步的优化,请随时告知。
阅读全文