POI获取模板文件,替换数据横纵动态表格、折线图、饼状图、折线饼状组合图

先说几个关键的点
pom.xml依赖

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version>
</dependency>
<dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.2</version><exclusions><exclusion><groupId>poi</groupId><artifactId>poi</artifactId></exclusion><exclusion><groupId>poi-ooxml</groupId><artifactId>poi-ooxml</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version><exclusions><exclusion><groupId>commons-io</groupId><artifactId>commons-io</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.3</version><exclusions><exclusion><groupId>commons-io</groupId><artifactId>commons-io</artifactId></exclusion></exclusions>
</dependency>

横纵动态表格

首先读取你的数据,做好List<Map<String, Object>> list的数据,进行横表格纵表格动态填充

//XWPFTemplate模板启动所需配置LoopRowTableRenderPolicy行表格、LoopColumnTableRenderPolicy列表格
RenderPolicy policy1 = new LoopRowTableRenderPolicy(false);
Map<RenderPolicy, List<String>> polines1 = MapUtil.builder(policy1, Arrays.asList("rankScoreMapList")).map();
RenderPolicy policy2 = new LoopColumnTableRenderPolicy(false);
Map<RenderPolicy, List<String>> polines2 = MapUtil.builder(policy2, Arrays.asList("RL")).map();
List<Map<RenderPolicy, List<String>>> configList = Arrays.asList(polines1, polines2);
//渲染生成Word
String result = processWordTemplate(filename, map, scoreMapList, configList, rankScoreMapList, rankTicketTypeMapList);
return result;

读取配置并渲染数据

@SneakyThrows
public String processWordTemplate(String filename, Map<String, Object> replacements, List<Map<String, Object>> scoreMapList, List<Map<RenderPolicy, List<String>>> configList, List<Map<String, Object>> rankScoreMapList, List<Map<String, Object>> rankTicketTypeMapList) {byte[] fileBytes = upmsService.getFileBytes(filename);ByteArrayInputStream bis = new ByteArrayInputStream(fileBytes);//读取配置Configure config = Configure.createDefault();if (ObjectUtil.isNotEmpty(configList)) {for (Map<RenderPolicy, List<String>> map : configList) {for (Map.Entry<RenderPolicy, List<String>> entry : map.entrySet()) {RenderPolicy key = entry.getKey();List<String> value = entry.getValue();value.stream().forEach(val -> config.customPolicy(val, key));}}}//1. 渲染文本和表格数据replacementsXWPFTemplate template = XWPFTemplate.compile(bis, config).render(replacements);XWPFDocument document = template.getXWPFDocument();//2. 继续处理 -> 更改图表模板 -> 饼状图、折线图List<POIXMLDocumentPart> relations = document.getRelations();//.....详细代码见最下方。//完成操作后保存文档ByteArrayOutputStream bos = new ByteArrayOutputStream();document.write(bos);byte[] bytes = bos.toByteArray();PoitlIOUtils.closeQuietlyMulti(template, bos);//关闭流MultipartFile multipartFile = new MockMultipartFile(filename + ".docx", filename + ".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", bytes);R r = headersRemoteUpmsService.upload(multipartFile);if (r != null && r.isOk() && r.getData() != null) {Map<String, Object> data = (Map<String, Object>) r.getData();if (DataJudgeUtil.isNotBankMapKey(data, "url")) {return data.get("url").toString();}}return null;}

效果图如下:
在这里插入图片描述
在这里插入图片描述
注意1:横动态图表会自动获取该行的宽度,然后等分到每一栏中,我们需要将变量的长度给扩大,如果需要自定义宽度,请先移步到其他博客。
注意2:如果和我的一样为不标准的表格,需要放到该列的前一列中的任一单元格去,如:得分{{RL}}。放到测评项目单元格是不对的!!
在这里插入图片描述在这里插入图片描述
更多可以参考官网:https://deepoove.com/poi-tl/#hack-loop-table

图表:

确保你的图表为这种excel表格,而不是普通的图片
在这里插入图片描述
在这里插入图片描述

图表填充(其实就是填充对应的excel表格,一行一行的填充数据)饼图为例

List<POIXMLDocumentPart> relations = document.getRelations();
for (POIXMLDocumentPart poixmlDocumentPart : relations) {if (poixmlDocumentPart instanceof XWPFChart) {XWPFChart chart = (XWPFChart) poixmlDocumentPart;XSSFSheet sheet = chart.getWorkbook().getSheetAt(0);XSSFCell cell = sheet.getRow(0).getCell(1);if (cell.getStringCellValue().equals("领导班子(A票)")) {// 过滤掉总分标签rankTicketTypeMapList = rankTicketTypeMapList.stream().filter(m -> !m.get("itemName").equals("总分")).collect(Collectors.toList());// 设置各指标得分的单元格for (int i = 0; i < rankTicketTypeMapList.size(); i++) {Row dataRow = sheet.getRow(i + 1);if (dataRow == null) {dataRow = sheet.createRow(i + 1);}//设置标签名Cell itemNameCell = dataRow.getCell(0);if (itemNameCell == null) {itemNameCell = dataRow.createCell(0);}itemNameCell.setCellValue(rankTicketTypeMapList.get(i).get("itemName").toString());itemNameCell.setCellType(CellType.STRING);// 设置得分单元格Cell scoreCellA = dataRow.getCell(1);if (scoreCellA == null) {scoreCellA = dataRow.createCell(1);}scoreCellA.setCellValue(Double.valueOf(rankTicketTypeMapList.get(i).get("score_A").toString()));scoreCellA.setCellType(CellType.NUMERIC);Cell scoreCellB = dataRow.getCell(2);if (scoreCellB == null) {scoreCellB = dataRow.createCell(2);}scoreCellB.setCellValue(Double.valueOf(rankTicketTypeMapList.get(i).get("score_B").toString()));scoreCellB.setCellType(CellType.NUMERIC);Cell scoreCellC = dataRow.getCell(3);if (scoreCellC == null) {scoreCellC = dataRow.createCell(3);}scoreCellC.setCellValue(Double.valueOf(rankTicketTypeMapList.get(i).get("score_C").toString()));scoreCellC.setCellType(CellType.NUMERIC);Cell scoreCellALL = dataRow.getCell(4);if (scoreCellALL == null) {scoreCellALL = dataRow.createCell(4);}scoreCellALL.setCellValue(Double.valueOf(rankTicketTypeMapList.get(i).get("score_ALL").toString()));scoreCellALL.setCellType(CellType.NUMERIC);}firstRow = 1;lastRow = rankTicketTypeMapList.size();firstCol = 1;lastCol = 4;// 为什么默认是八行?可能和建表图的时候添加了八行?删除多余的行for (int i = sheet.getLastRowNum(); i > rankTicketTypeMapList.size() + 1; i--) {sheet.removeRow(sheet.getRow(i));}}
}

填充完数据,需要刷新图表,才会把新数据应用到图表中:
s.replaceData(cat, val);chart.plot(chartData);

XDDFChartData chartData = chart.getChartSeries().get(0);
if (chartData instanceof XDDFPieChartData) {//判断类型为饼图XDDFChartData.Series s = chartData.getSeries().get(0);XDDFDataSource cat = XDDFDataSourcesFactory.fromStringCellRange(sheet,new CellRangeAddress(firstRow, lastRow, 0, 0));XDDFNumericalDataSource val = XDDFDataSourcesFactory.fromNumericCellRange(sheet,new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));s.replaceData(cat, val);chart.plot(chartData);
}

折线图与柱状图的组合图需要分别获取并刷新

//应用数据后刷新
XDDFChartData chartData = chart.getChartSeries().get(0);XDDFChartData chartData0 = chart.getChartSeries().get(0);//XDDFBarChartData柱状系列数据
XDDFChartData chartData1 = chart.getChartSeries().get(1);//XDDFLineChartData折线系列数据XDDFDataSource cat = XDDFDataSourcesFactory.fromStringCellRange(sheet,new CellRangeAddress(firstRow, lastRow, 0, 0));
for (int i = 0; i < chartData0.getSeries().size(); i++) {XDDFChartData.Series s = chartData0.getSeries().get(i);XDDFNumericalDataSource val = XDDFDataSourcesFactory.fromNumericCellRange(sheet,new CellRangeAddress(firstRow, lastRow, firstCol + i, firstCol + i));s.replaceData(cat, val);
}
for (int i = 0; i < chartData1.getSeries().size(); i++) {XDDFChartData.Series s = chartData1.getSeries().get(i);XDDFNumericalDataSource val = XDDFDataSourcesFactory.fromNumericCellRange(sheet,new CellRangeAddress(firstRow, lastRow, firstCol + i + 2, firstCol + i + 2));s.replaceData(cat, val);
}
chart.plot(chartData0);
chart.plot(chartData1);

效果如图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此组合图的编辑如下:(根据自己需要的设置,填充数据后也要换成自己的刷新方式)
在这里插入图片描述

全部代码如下:

前面一直都在获取数据,主要的代码去见processWordTemplate
折线图、饼状图、折线饼状组合图均见processWordTemplate方法

package com.grp.digitization.hr.common.rest.kpiticketfeedback;import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.plugin.table.LoopColumnTableRenderPolicy;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.deepoove.poi.policy.RenderPolicy;
import com.deepoove.poi.util.PoitlIOUtils;
import com.grp.digitization.admin.api.feign.RemoteUpmsService;
import com.grp.digitization.common.core.util.R;
import com.grp.digitization.common.security.annotation.Inner;
import com.grp.digitization.hr.feign.hr.HeadersRemoteUpmsService;
import com.grp.digitization.hr.utils.DataJudgeUtil;
import com.grp.digitization.platform.server.GrpServer;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.util.*;
import java.util.stream.Collectors;@Slf4j
@RestController()
@RequestMapping("/KpiTicketFeedback")
@Api(value = "KPICadreFeedbackReport", tags = "中层干部考核任务->生成中层干部反馈报告WORD文件")
public class KpiTicketFeedbackController {@Resourceprivate RemoteUpmsService upmsService;@Autowiredprivate HeadersRemoteUpmsService headersRemoteUpmsService;//    private static final String filename = "tohi-FeedbackReports_Final.docx";private static final String filename = "tohi-88b5591ba7064d43856e162d93adb9c2.docx";@SneakyThrows@RequestMapping("/exportFeedbackWord/{code}")@Inner(value = false)@ApiOperation(value = "exportFeedbackWord", notes = "生成中层干部反馈报告")public R exportFeedbackWord(@PathVariable String code) {//拿到该评分任务下的每个用户,为每个用户生成一份反馈报告String personSql = "SELECT obj.USERNAME,obj.NAME,obj.DENAME,su.US_TITLE,mv.ENDTIME,mv.TITLE,mv.YEAR\n" +"FROM `middlecadresobjflow` obj LEFT JOIN middlecadresreview mv ON obj.MIDDLECADRESREVIEWCODE = mv.MIDDLECADRESREVIEWCODE LEFT JOIN sys_user su ON obj.USERNAME = su.username \n" +"WHERE obj.MIDDLECADRESREVIEWCODE = '" + code + "'";List<Map<String, Object>> personMapList = GrpServer.getGrpServer().excuteQueryListMap(personSql);Map<String, String> resultMap = personMapList.stream().collect(Collectors.toMap(m -> m.get("USERNAME").toString(),m -> generatePersonWord(code, personMapList, m.get("USERNAME").toString())//调用方法获取生成的文件的URL));//写入数据库for (Map.Entry<String, String> entry : resultMap.entrySet()) {log.info("生成中层干部反馈报告key:{},value:{}", entry.getKey(), entry.getValue());String updateSql = "UPDATE middlecadresobjflow SET FEEDBACK_URL = '" + entry.getValue() + "'" +" WHERE MIDDLECADRESREVIEWCODE = '" + code + "' AND USERNAME = '" + entry.getKey() + "'";GrpServer.getGrpServer().excuteUpdate(updateSql);}return R.ok(resultMap);}@SneakyThrowsprivate String generatePersonWord(String code, List<Map<String, Object>> personMapList, String username) {if (StringUtils.isEmpty(username)) {return "";}Map<String, Object> map = new HashMap<>();//声明存放数据的mapOptional<Map<String, Object>> first = personMapList.stream().filter(m -> m.containsKey("USERNAME") && m.get("USERNAME").toString().equals(username)).findFirst();if (first.isPresent()) {Map<String, Object> tmp = first.get();map.put("name", DataJudgeUtil.isNotBankMapKey(tmp, "NAME") ? tmp.get("NAME").toString() : "");map.put("dept", DataJudgeUtil.isNotBankMapKey(tmp, "DENAME") ? tmp.get("DENAME").toString() : "");map.put("title", DataJudgeUtil.isNotBankMapKey(tmp, "US_TITLE") ? tmp.get("US_TITLE").toString() : "");map.put("date", DataJudgeUtil.isNotBankMapKey(tmp, "ENDTIME") ? tmp.get("ENDTIME").toString().split("T")[0] : "");map.put("theme", DataJudgeUtil.isNotBankMapKey(tmp, "TITLE") ? tmp.get("TITLE").toString() : "");map.put("year", DataJudgeUtil.isNotBankMapKey(tmp, "YEAR") ? tmp.get("YEAR").toString().split("-")[0] : "");}//获取票类型以及数量(有效)String ticketSql = "SELECT TICKETTYPE,WEIGHT,COUNT(*) AS NUM FROM `middlecadresscore` \n" +"WHERE MIDDLECADRESREVIEWCODE = '" + code + "' AND TICKETSTATE = '1' GROUP BY TICKETTYPE,WEIGHT";List<Map<String, Object>> ticketMapList = GrpServer.getGrpServer().excuteQueryListMap(ticketSql);long effective_SUM = ticketMapList.stream().map(m -> Integer.valueOf(m.get("NUM").toString())).mapToLong(Integer::intValue).sum();Double wight_SUM = ticketMapList.stream().map(m -> Double.valueOf(m.get("WEIGHT").toString())).mapToDouble(Double::doubleValue).sum();ticketMapList.forEach(m -> {int count = Integer.valueOf(m.get("NUM").toString());double percentage = (count * 100.0) / effective_SUM;String percentageStr = String.format("%.2f", percentage) + "%";map.put("EFF_" + m.get("TICKETTYPE").toString(), m.get("NUM").toString());map.put("PE_" + m.get("TICKETTYPE").toString(), percentageStr);map.put("WIGHT_" + m.get("TICKETTYPE").toString(), String.format("%.2f", Double.valueOf(m.get("WEIGHT").toString())) + "%");});map.put("EFF_SUM", String.valueOf(effective_SUM));map.put("WIGHT_SUM", String.format("%.2f", wight_SUM) + "%");//总票数String all_ticketSql = "SELECT TICKETTYPE,WEIGHT,COUNT(*) AS NUM FROM `middlecadresscore` \n" +"WHERE MIDDLECADRESREVIEWCODE = '" + code + "' GROUP BY TICKETTYPE,WEIGHT";List<Map<String, Object>> all_ticketMapList = GrpServer.getGrpServer().excuteQueryListMap(all_ticketSql);long all_SUM = all_ticketMapList.stream().map(m -> Integer.valueOf(m.get("NUM").toString())).mapToLong(Integer::intValue).sum();all_ticketMapList.forEach(m -> {int count = Integer.valueOf(m.get("NUM").toString());double percentage = (count * 100.0) / all_SUM;String percentageStr = String.format("%.2f", percentage) + "%";map.put("ALL_" + m.get("TICKETTYPE").toString(), m.get("NUM").toString());map.put("PA_" + m.get("TICKETTYPE").toString(), percentageStr);});map.put("ALL_SUM", String.valueOf(all_SUM));// 更改图表模板-> 饼状图//统计所有人的测评项目、综合得分String all_scoreSql = "SELECT OBJECTNO,itemCode,itemName,SUM(SCORE*WEIGHT)/100 as synthesisScore FROM \n" +"(SELECT mcp.itemCode,mcp.itemName,mcp.OBJECTNO,ms.ticketType,ms.WEIGHT,SUM(mcp.SCORE) / COUNT(*) AS SCORE FROM middlecadresscorecp mcp \n" +"LEFT JOIN middlecadresscore ms ON ms.MIDDLECADRESSCORECODE = mcp.MIDDLECADRESSCORECODE WHERE ms.MIDDLECADRESREVIEWCODE = '" + code + "' AND ms.TICKETSTATE = '1' \n" +"GROUP BY mcp.itemCode,mcp.itemName,mcp.OBJECTNO, ms.ticketType, ms.WEIGHT) tmp \n" +"GROUP BY itemCode,itemName,OBJECTNO \n";List<Map<String, Object>> all_scoreMapList = GrpServer.getGrpServer().excuteQueryListMap(all_scoreSql);//统计同组人所有人的测评项目的综合得分的最低分、平均分、最高分minScore、maxScore、avgScore// 先计算统计每个itemCode的信息Map<String, DoubleSummaryStatistics> statisticsMap = all_scoreMapList.stream().collect(Collectors.groupingBy(m -> m.get("itemCode").toString(),Collectors.mapping(m -> Double.valueOf(m.get("synthesisScore").toString()), Collectors.summarizingDouble(Double::doubleValue))));all_scoreMapList.forEach(m -> {String itemCode = m.get("itemCode").toString();DoubleSummaryStatistics stats = statisticsMap.get(itemCode);if (stats != null) {m.put("minScore", stats.getMin());m.put("maxScore", stats.getMax());m.put("avgScore", stats.getAverage());}});//计算个人的相关数据-折线图List<Map<String, Object>> scoreMapList = all_scoreMapList.stream().filter(m -> m.containsKey("OBJECTNO") && m.get("OBJECTNO").toString().equals(username)).collect(Collectors.toList());double score = scoreMapList.stream().map(m -> Double.valueOf(m.get("synthesisScore").toString())).mapToDouble(Double::doubleValue).sum();double averageScore = scoreMapList.stream().map(m -> Double.valueOf(m.get("synthesisScore").toString())).mapToDouble(Double::doubleValue).average().orElse(0.0);List<String> itemName_high = scoreMapList.stream().filter(m -> Double.valueOf(m.get("synthesisScore").toString()) >= averageScore).map(m -> m.get("itemName").toString()).collect(Collectors.toList());List<String> itemName_low = scoreMapList.stream().filter(m -> Double.valueOf(m.get("synthesisScore").toString()) < averageScore).map(m -> m.get("itemName").toString()).collect(Collectors.toList());map.put("SCORE", String.format("%.2f", score));map.put("AVG_SCORE", String.format("%.2f", averageScore));map.put("ITEM_HIGH", itemName_high.isEmpty() ? "无测评项目" : String.join("、", itemName_high));map.put("ITEM_LOW", itemName_low.isEmpty() ? "无测评项目" : String.join("、", itemName_low));//为all_scoreMapList每个OBJECTNO添加总分的一行数据List<String> userList = all_scoreMapList.stream().map(m -> m.get("OBJECTNO").toString()).distinct().collect(Collectors.toList());long count = userList.size();userList.forEach(u -> {double minScoreSum = all_scoreMapList.stream().filter(m -> m.get("OBJECTNO").toString().equals(u)).map(m -> Double.valueOf(m.get("minScore").toString())).mapToDouble(Double::doubleValue).sum();double avgScoreSum = all_scoreMapList.stream().filter(m -> m.get("OBJECTNO").toString().equals(u)).map(m -> Double.valueOf(m.get("avgScore").toString())).mapToDouble(Double::doubleValue).sum();double maxScoreSum = all_scoreMapList.stream().filter(m -> m.get("OBJECTNO").toString().equals(u)).map(m -> Double.valueOf(m.get("maxScore").toString())).mapToDouble(Double::doubleValue).sum();double synthesisScoreSum = all_scoreMapList.stream().filter(m -> m.get("OBJECTNO").toString().equals(u)).map(m -> Double.valueOf(m.get("synthesisScore").toString())).mapToDouble(Double::doubleValue).sum();HashMap<String, Object> tmpMap = new HashMap<>();tmpMap.put("OBJECTNO", u);tmpMap.put("itemCode", 0);//总分编号设置为0tmpMap.put("itemName", "总分");tmpMap.put("minScore", minScoreSum);tmpMap.put("avgScore", avgScoreSum);tmpMap.put("maxScore", maxScoreSum);tmpMap.put("synthesisScore", synthesisScoreSum);all_scoreMapList.add(tmpMap);});//个人排名渲染的listList<Map<String, Object>> rankScoreMapList = all_scoreMapList.stream().filter(m -> m.get("OBJECTNO").toString().equals(username)).collect(Collectors.toList());rankScoreMapList.forEach(m -> {long rank = all_scoreMapList.stream().filter(m2 -> m2.get("itemCode").equals(m.get("itemCode")) && Double.valueOf(m2.get("synthesisScore").toString()) > Double.valueOf(m.get("synthesisScore").toString())).count() + 1;m.put("rank", rank + "/" + count);});//score格式化为两位小数rankScoreMapList.forEach(m -> {m.put("minScore", String.format("%.2f", Double.valueOf(m.get("minScore").toString())));m.put("avgScore", String.format("%.2f", Double.valueOf(m.get("avgScore").toString())));m.put("maxScore", String.format("%.2f", Double.valueOf(m.get("maxScore").toString())));m.put("synthesisScore", String.format("%.2f", Double.valueOf(m.get("synthesisScore").toString())));});map.put("rankScoreMapList", rankScoreMapList);List<String> beaItemName = rankScoreMapList.stream().filter(m -> Math.abs(Double.valueOf(m.get("synthesisScore").toString()) - averageScore) < 0.25).map(m -> m.get("itemName").toString()).collect(Collectors.toList());map.put("BEA_ITEM_NAME", beaItemName.isEmpty() ? "无测评项目" : String.join("、", beaItemName));//统计同组人所有人的测评项目的A票score_A,B票score_B,C票score_C,(规则,票类型相同的加和求平均值)以及总分score_ALL(权重wight)String all_ticketTypeSql = "SELECT tmp.OBJECTNO,tmp.itemCode,tmp.itemName,SUM(CASE tmp.ticketType WHEN 'A' THEN tmp.score ELSE 0 END) AS score_A,SUM(CASE tmp.ticketType WHEN 'B' THEN tmp.score ELSE 0 END) AS score_B,SUM(CASE tmp.ticketType WHEN 'C' THEN tmp.score ELSE 0 END) AS score_C, \n" +"ROUND(SUM(CASE tmp.ticketType WHEN 'A' THEN tmp.score * tmp.WEIGHT / 100.0 ELSE 0 END) + SUM(CASE tmp.ticketType WHEN 'B' THEN tmp.score * tmp.WEIGHT / 100.0 ELSE 0 END) + SUM(CASE tmp.ticketType WHEN 'C' THEN tmp.score * tmp.WEIGHT / 100.0 ELSE 0 END), 2) AS score_ALL \n" +"FROM( SELECT mcp.itemCode,mcp.itemName,mcp.OBJECTNO,ms.ticketType,ms.WEIGHT,SUM(mcp.SCORE) / COUNT(*) AS SCORE FROM middlecadresscorecp mcp LEFT JOIN middlecadresscore ms ON ms.MIDDLECADRESSCORECODE = mcp.MIDDLECADRESSCORECODE\n" +"    WHERE ms.MIDDLECADRESREVIEWCODE = '" + code + "' AND ms.TICKETSTATE = '1' GROUP BY mcp.itemCode, mcp.itemName, mcp.OBJECTNO, ms.ticketType, ms.WEIGHT\n" +") tmp GROUP BY tmp.itemCode, tmp.itemName, tmp.OBJECTNO\n";List<Map<String, Object>> all_ticketTypeMapList = GrpServer.getGrpServer().excuteQueryListMap(all_ticketTypeSql);//为all_ticketTypeMapList每个OBJECTNO添加总分的一行数据userList.forEach(u -> {double score_A = all_ticketTypeMapList.stream().filter(m -> m.get("OBJECTNO").toString().equals(u)).map(m -> Double.valueOf(m.get("score_A").toString())).mapToDouble(Double::doubleValue).sum();double score_B = all_ticketTypeMapList.stream().filter(m -> m.get("OBJECTNO").toString().equals(u)).map(m -> Double.valueOf(m.get("score_B").toString())).mapToDouble(Double::doubleValue).sum();double score_C = all_ticketTypeMapList.stream().filter(m -> m.get("OBJECTNO").toString().equals(u)).map(m -> Double.valueOf(m.get("score_C").toString())).mapToDouble(Double::doubleValue).sum();double score_ALL = all_ticketTypeMapList.stream().filter(m -> m.get("OBJECTNO").toString().equals(u)).map(m -> Double.valueOf(m.get("score_ALL").toString())).mapToDouble(Double::doubleValue).sum();HashMap<String, Object> tmpMap = new HashMap<>();tmpMap.put("OBJECTNO", u);tmpMap.put("itemCode", 0);//总分编号设置为0tmpMap.put("itemName", "总分");tmpMap.put("score_A", score_A);tmpMap.put("score_B", score_B);tmpMap.put("score_C", score_C);tmpMap.put("score_ALL", score_ALL);all_ticketTypeMapList.add(tmpMap);});//过滤成个人信息并添加排名rank信息List<Map<String, Object>> rankTicketTypeMapList = all_ticketTypeMapList.stream().filter(m -> m.get("OBJECTNO").toString().equals(username)).collect(Collectors.toList());rankTicketTypeMapList.forEach(m -> {long rank_A = all_ticketTypeMapList.stream().filter(m2 -> m2.get("itemCode").equals(m.get("itemCode")) && Double.valueOf(m2.get("score_A").toString()) > Double.valueOf(m.get("score_A").toString())).count() + 1;m.put("rank_A", rank_A + "/" + count);long rank_B = all_ticketTypeMapList.stream().filter(m2 -> m2.get("itemCode").equals(m.get("itemCode")) && Double.valueOf(m2.get("score_B").toString()) > Double.valueOf(m.get("score_B").toString())).count() + 1;m.put("rank_B", rank_B + "/" + count);long rank_C = all_ticketTypeMapList.stream().filter(m2 -> m2.get("itemCode").equals(m.get("itemCode")) && Double.valueOf(m2.get("score_C").toString()) > Double.valueOf(m.get("score_C").toString())).count() + 1;m.put("rank_C", rank_C + "/" + count);long rank_ALL = all_ticketTypeMapList.stream().filter(m2 -> m2.get("itemCode").equals(m.get("itemCode")) && Double.valueOf(m2.get("score_ALL").toString()) > Double.valueOf(m.get("score_ALL").toString())).count() + 1;m.put("rank_ALL", rank_ALL + "/" + count);});//score格式化为两位小数rankTicketTypeMapList.forEach(m -> {m.put("score_A", String.format("%.2f", Double.valueOf(m.get("score_A").toString())));m.put("score_B", String.format("%.2f", Double.valueOf(m.get("score_B").toString())));m.put("score_C", String.format("%.2f", Double.valueOf(m.get("score_C").toString())));m.put("score_ALL", String.format("%.2f", Double.valueOf(m.get("score_ALL").toString())));});
//        map.put("rankTicketTypeMapList",rankTicketTypeMapList);map.put("RL", rankTicketTypeMapList);//提取每张票上的建议String suggestionSql = "SELECT SUGGESTION FROM `middlecadresscore` WHERE MIDDLECADRESREVIEWCODE = '" + code + "' AND TICKETSTATE = '1'";List<Map<String, Object>> suggestionMapList = GrpServer.getGrpServer().excuteQueryListMap(suggestionSql);if (suggestionMapList.size() >= 0) {List<String> suggestionList = suggestionMapList.stream().filter(m -> m != null && m.containsKey("SUGGESTION") && DataJudgeUtil.isNotBankMapKey(m, "SUGGESTION")).map(m -> m.get("SUGGESTION").toString()).collect(Collectors.toList());map.put("suggestion", String.join("\n", suggestionList));} else {map.put("suggestion", "无");}//XWPFTemplate模板启动所需配置LoopRowTableRenderPolicy行表格、LoopColumnTableRenderPolicy列表格RenderPolicy policy1 = new LoopRowTableRenderPolicy(false);Map<RenderPolicy, List<String>> polines1 = MapUtil.builder(policy1, Arrays.asList("rankScoreMapList")).map();RenderPolicy policy2 = new LoopColumnTableRenderPolicy(false);Map<RenderPolicy, List<String>> polines2 = MapUtil.builder(policy2, Arrays.asList("RL")).map();List<Map<RenderPolicy, List<String>>> configList = Arrays.asList(polines1, polines2);//渲染生成WordString result = processWordTemplate(filename, map, scoreMapList, configList, rankScoreMapList, rankTicketTypeMapList);return result;}@SneakyThrowspublic String processWordTemplate(String filename, Map<String, Object> replacements, List<Map<String, Object>> scoreMapList, List<Map<RenderPolicy, List<String>>> configList, List<Map<String, Object>> rankScoreMapList, List<Map<String, Object>> rankTicketTypeMapList) {byte[] fileBytes = upmsService.getFileBytes(filename);ByteArrayInputStream bis = new ByteArrayInputStream(fileBytes);//读取配置Configure config = Configure.createDefault();if (ObjectUtil.isNotEmpty(configList)) {for (Map<RenderPolicy, List<String>> map : configList) {for (Map.Entry<RenderPolicy, List<String>> entry : map.entrySet()) {RenderPolicy key = entry.getKey();List<String> value = entry.getValue();value.stream().forEach(val -> config.customPolicy(val, key));}}}//1. 渲染文本和表格数据replacementsXWPFTemplate template = XWPFTemplate.compile(bis, config).render(replacements);XWPFDocument document = template.getXWPFDocument();//2. 继续处理 -> 更改图表模板 -> 饼状图、折线图List<POIXMLDocumentPart> relations = document.getRelations();for (POIXMLDocumentPart poixmlDocumentPart : relations) {if (poixmlDocumentPart instanceof XWPFChart) {int firstRow = 0;int lastRow = 0;int firstCol = 0;int lastCol = 0;XWPFChart chart = (XWPFChart) poixmlDocumentPart;XSSFSheet sheet = chart.getWorkbook().getSheetAt(0);XSSFCell cell = sheet.getRow(0).getCell(1);//饼图if (cell.getStringCellValue().equals("主体人数")) {sheet.getRow(1).getCell(1).setCellValue(percentageStrToDouble(replacements.get("PE_A").toString()));sheet.getRow(2).getCell(1).setCellValue(percentageStrToDouble(replacements.get("PE_B").toString()));sheet.getRow(3).getCell(1).setCellValue(percentageStrToDouble(replacements.get("PE_C").toString()));sheet.getRow(1).getCell(1).setCellType(CellType.NUMERIC);sheet.getRow(2).getCell(1).setCellType(CellType.NUMERIC);sheet.getRow(3).getCell(1).setCellType(CellType.NUMERIC);firstRow = 1;lastRow = 3;firstCol = 1;lastCol = 1;}//饼图if (cell.getStringCellValue().equals("主体权重")) {sheet.getRow(1).getCell(1).setCellValue(percentageStrToDouble(replacements.get("WIGHT_A").toString()));sheet.getRow(2).getCell(1).setCellValue(percentageStrToDouble(replacements.get("WIGHT_B").toString()));sheet.getRow(3).getCell(1).setCellValue(percentageStrToDouble(replacements.get("WIGHT_C").toString()));sheet.getRow(1).getCell(1).setCellType(CellType.NUMERIC);sheet.getRow(2).getCell(1).setCellType(CellType.NUMERIC);sheet.getRow(3).getCell(1).setCellType(CellType.NUMERIC);firstRow = 1;lastRow = 3;firstCol = 1;lastCol = 1;}//折线图if (cell.getStringCellValue().equals("各指标得分")) {double averageScore = scoreMapList.stream().map(m -> Double.valueOf(m.get("synthesisScore").toString())).mapToDouble(Double::doubleValue).average().orElse(0.0);String formattedAverageScore = String.format("%.2f", averageScore);sheet.getRow(0).getCell(2).setCellValue("各指标平均分 " + formattedAverageScore);//TODO 设置标题后怎么刷新??// 设置各指标得分的单元格for (int i = 0; i < scoreMapList.size(); i++) {Row dataRow = sheet.getRow(i + 1);if (dataRow == null) {dataRow = sheet.createRow(i + 1);}//设置标签名Cell itemNameCell = dataRow.getCell(0);if (itemNameCell == null) {itemNameCell = dataRow.createCell(0);}itemNameCell.setCellValue(scoreMapList.get(i).get("itemName").toString());itemNameCell.setCellType(CellType.STRING);// 设置得分单元格Cell scoreCell = dataRow.getCell(1);if (scoreCell == null) {scoreCell = dataRow.createCell(1);}scoreCell.setCellValue(Double.valueOf(scoreMapList.get(i).get("synthesisScore").toString()));scoreCell.setCellType(CellType.NUMERIC);// 设置平均分单元格Cell avgCell = dataRow.getCell(2);if (avgCell == null) {avgCell = dataRow.createCell(2);}avgCell.setCellValue(Double.valueOf(formattedAverageScore));avgCell.setCellType(CellType.NUMERIC);}firstRow = 1;lastRow = scoreMapList.size();firstCol = 1;lastCol = 2;// 为什么默认是八行?可能和建表图的时候添加了八行?删除多余的行for (int i = sheet.getLastRowNum(); i > scoreMapList.size() + 1; i--) {sheet.removeRow(sheet.getRow(i));}}//折线图与柱状图的组合图if (cell.getStringCellValue().equals("同组人员得分范围下限")) {// 过滤掉总分标签rankScoreMapList = rankScoreMapList.stream().filter(m -> !m.get("itemName").equals("总分")).collect(Collectors.toList());// 设置各指标得分的单元格for (int i = 0; i < rankScoreMapList.size(); i++) {Row dataRow = sheet.getRow(i + 1);if (dataRow == null) {dataRow = sheet.createRow(i + 1);}//设置标签名Cell itemNameCell = dataRow.getCell(0);if (itemNameCell == null) {itemNameCell = dataRow.createCell(0);}itemNameCell.setCellValue(rankScoreMapList.get(i).get("itemName").toString());itemNameCell.setCellType(CellType.STRING);// 设置同组人员得分下限Cell scoreLowCell = dataRow.getCell(1);if (scoreLowCell == null) {scoreLowCell = dataRow.createCell(1);}scoreLowCell.setCellValue(Double.valueOf(rankScoreMapList.get(i).get("minScore").toString()));scoreLowCell.setCellType(CellType.NUMERIC);// 设置同组人员得分范围Cell scoreRangeCell = dataRow.getCell(2);if (scoreRangeCell == null) {scoreRangeCell = dataRow.createCell(2);}scoreRangeCell.setCellValue(Double.valueOf(rankScoreMapList.get(i).get("maxScore").toString()) - Double.valueOf(rankScoreMapList.get(i).get("minScore").toString()));scoreRangeCell.setCellType(CellType.NUMERIC);// 设置平均分单元格Cell avgCell = dataRow.getCell(3);if (avgCell == null) {avgCell = dataRow.createCell(3);}avgCell.setCellValue(Double.valueOf(rankScoreMapList.get(i).get("avgScore").toString()));avgCell.setCellType(CellType.NUMERIC);// 设置平均分单元格Cell synthesisScoreCell = dataRow.getCell(4);if (synthesisScoreCell == null) {synthesisScoreCell = dataRow.createCell(4);}synthesisScoreCell.setCellValue(Double.valueOf(rankScoreMapList.get(i).get("synthesisScore").toString()));synthesisScoreCell.setCellType(CellType.NUMERIC);}firstRow = 1;lastRow = rankScoreMapList.size();firstCol = 1;lastCol = 4;//删除多余的行for (int i = sheet.getLastRowNum(); i > rankScoreMapList.size() + 1; i--) {sheet.removeRow(sheet.getRow(i));}}//折线图if (cell.getStringCellValue().equals("领导班子(A票)")) {// 过滤掉总分标签rankTicketTypeMapList = rankTicketTypeMapList.stream().filter(m -> !m.get("itemName").equals("总分")).collect(Collectors.toList());// 设置各指标得分的单元格for (int i = 0; i < rankTicketTypeMapList.size(); i++) {Row dataRow = sheet.getRow(i + 1);if (dataRow == null) {dataRow = sheet.createRow(i + 1);}//设置标签名Cell itemNameCell = dataRow.getCell(0);if (itemNameCell == null) {itemNameCell = dataRow.createCell(0);}itemNameCell.setCellValue(rankTicketTypeMapList.get(i).get("itemName").toString());itemNameCell.setCellType(CellType.STRING);// 设置得分单元格Cell scoreCellA = dataRow.getCell(1);if (scoreCellA == null) {scoreCellA = dataRow.createCell(1);}scoreCellA.setCellValue(Double.valueOf(rankTicketTypeMapList.get(i).get("score_A").toString()));scoreCellA.setCellType(CellType.NUMERIC);Cell scoreCellB = dataRow.getCell(2);if (scoreCellB == null) {scoreCellB = dataRow.createCell(2);}scoreCellB.setCellValue(Double.valueOf(rankTicketTypeMapList.get(i).get("score_B").toString()));scoreCellB.setCellType(CellType.NUMERIC);Cell scoreCellC = dataRow.getCell(3);if (scoreCellC == null) {scoreCellC = dataRow.createCell(3);}scoreCellC.setCellValue(Double.valueOf(rankTicketTypeMapList.get(i).get("score_C").toString()));scoreCellC.setCellType(CellType.NUMERIC);Cell scoreCellALL = dataRow.getCell(4);if (scoreCellALL == null) {scoreCellALL = dataRow.createCell(4);}scoreCellALL.setCellValue(Double.valueOf(rankTicketTypeMapList.get(i).get("score_ALL").toString()));scoreCellALL.setCellType(CellType.NUMERIC);}firstRow = 1;lastRow = rankTicketTypeMapList.size();firstCol = 1;lastCol = 4;// 为什么默认是八行?可能和建表图的时候添加了八行?删除多余的行for (int i = sheet.getLastRowNum(); i > rankTicketTypeMapList.size() + 1; i--) {sheet.removeRow(sheet.getRow(i));}}//应用数据后刷新XDDFChartData chartData = chart.getChartSeries().get(0);if (chartData instanceof XDDFPieChartData) {//饼图XDDFChartData.Series s = chartData.getSeries().get(0);XDDFDataSource cat = XDDFDataSourcesFactory.fromStringCellRange(sheet,new CellRangeAddress(firstRow, lastRow, 0, 0));XDDFNumericalDataSource val = XDDFDataSourcesFactory.fromNumericCellRange(sheet,new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));s.replaceData(cat, val);chart.plot(chartData);} else if (chartData instanceof XDDFLineChartData) {//折线图XDDFDataSource cat = XDDFDataSourcesFactory.fromStringCellRange(sheet,new CellRangeAddress(firstRow, lastRow, 0, 0));for (int i = 0; i < chartData.getSeries().size(); i++) {XDDFChartData.Series s = chartData.getSeries().get(i);XDDFNumericalDataSource val = XDDFDataSourcesFactory.fromNumericCellRange(sheet,new CellRangeAddress(firstRow, lastRow, firstCol + i, firstCol + i));s.replaceData(cat, val);}chart.plot(chartData);} else {//折线图与柱状图的组合图XDDFChartData chartData0 = chart.getChartSeries().get(0);//XDDFBarChartData柱状系列数据XDDFChartData chartData1 = chart.getChartSeries().get(1);//XDDFLineChartData折线系列数据XDDFDataSource cat = XDDFDataSourcesFactory.fromStringCellRange(sheet,new CellRangeAddress(firstRow, lastRow, 0, 0));for (int i = 0; i < chartData0.getSeries().size(); i++) {XDDFChartData.Series s = chartData0.getSeries().get(i);XDDFNumericalDataSource val = XDDFDataSourcesFactory.fromNumericCellRange(sheet,new CellRangeAddress(firstRow, lastRow, firstCol + i, firstCol + i));s.replaceData(cat, val);}for (int i = 0; i < chartData1.getSeries().size(); i++) {XDDFChartData.Series s = chartData1.getSeries().get(i);XDDFNumericalDataSource val = XDDFDataSourcesFactory.fromNumericCellRange(sheet,new CellRangeAddress(firstRow, lastRow, firstCol + i + 2, firstCol + i + 2));s.replaceData(cat, val);}chart.plot(chartData0);chart.plot(chartData1);}}}//完成操作后保存文档ByteArrayOutputStream bos = new ByteArrayOutputStream();document.write(bos);byte[] bytes = bos.toByteArray();PoitlIOUtils.closeQuietlyMulti(template, bos);//关闭流MultipartFile multipartFile = new MockMultipartFile(filename + ".docx", filename + ".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", bytes);R r = headersRemoteUpmsService.upload(multipartFile);if (r != null && r.isOk() && r.getData() != null) {Map<String, Object> data = (Map<String, Object>) r.getData();if (DataJudgeUtil.isNotBankMapKey(data, "url")) {return data.get("url").toString();}}return null;}public Double percentageStrToDouble(String percentageStr) {String cleanedStr = percentageStr.replace("%", "");double value = Double.parseDouble(cleanedStr);double result = value / 100;return result;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/149404.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

鸭脖变“刺客”,啃不起了

撰文&#xff5c;ANGELICA 编辑&#xff5c;ANGELICA 审核&#xff5c;烨 Lydia 声明&#xff5c;图片来源网络。日晞研究所原创文章&#xff0c;如需转载请留言申请开白。 你有多久没吃卤味了&#xff1f; 2020年之后&#xff0c;人们对于几大卤味巨头的关注度正在下降。 …

【MySQL 04】数据类型

目录 1.数据类型分类 2.数值类型 2.1 tinyint 类型 2.2 bit类型 2.3 float类型 2.4decimal 3.字符串类型 3.1 char类型 3.2 varchar类型 4.日期和时间类型 6. enum和set类型 6.1.enum和set类型简介&#xff1a; 6.2.enum和set的一般使用方法 6.3.用数字的方式…

业务数据批量插入数据库实践

业务数据如何存储一直以来都是项目开发中的一个比较重要的话题。我们要从资源的利用率&#xff0c;业务场景和技术实现多个方面考虑存储的问题。“抛开业务谈技术就是耍流氓”&#xff0c;所有技术架构都要站在实际的业务场景中分析。比如个人端的产品&#xff0c;这种就属于读…

fiddler抓包11_列表显示服务器IP (配置文件)

请求列表默认不显示服务器IP字段&#xff0c;也无法从定制列窗口添加&#xff0c;可以修改CustomRules.js实现。 ① 菜单栏“Rules”&#xff08;规则&#xff09; - “Customize Rules...”&#xff08;自定义规则&#xff09;&#xff0c;打开CustomRules.js文件。 &#xf…

基于stm32的跑步机控制系统设计-设计说明书

设计摘要&#xff1a; 随着人们对健康和健身的关注增加&#xff0c;跑步机逐渐成为室内健身的主要设备之一。本文提出了一种基于STM32的跑步机控制系统设计&#xff0c;旨在实现对跑步机的运行速度、倾斜角度和运动模式等参数的精确控制&#xff0c;提供更好的健身体验。 首先…

vue3开发中易遗漏的常见知识点

文章目录 组件样式的特性Scoped CSS之局部样式的泄露Scoped CSS之深度选择器CSS Modules在CSS中使用v-bind 非props属性继承组件通信父子组件的相互通信props/$emit父组件传递数据给子组件子组件传递数据给父组件 非父子组件的相互通信Provide/inject全局事件总线 组件插槽作用…

LVGL 控件之消息框(lv_msgbox)

目录 一、概述二、消息框1、创建消息框2、获取消息框的组成部分3、关闭消息框部件4、消息框部件事件5、API 函数 一、概述 消息框部件是由多个小部件构建而成的&#xff0c;包括&#xff1a;lv_obj、lv_btn、lv_label 和 lv_btnmatrix 部件&#xff0c;示意图如下所示&#xf…

简单题83. 删除排序链表中的重复元素 (Java)20240920

问题描述&#xff1a; java&#xff1a; /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.val val; th…

【LLM学习之路】9月23日24日 第十、十一天 Attention代码解读

【LLM学习之路】9月23日24日 第十、十一天 Attention代码解读 Transformer模型大致分为三类 纯 Encoder 模型&#xff08;例如 BERT&#xff09;&#xff0c;又称自编码 (auto-encoding) Transformer 模型&#xff1b;纯 Decoder 模型&#xff08;例如 GPT&#xff09;&#…

基于python的django微博内容网络分析系统,实现文本划分词结构

本项目旨在开发一个基于Python的Django框架的微博内容网络分析系统&#xff0c;聚焦于微博文本的分词处理、名词提取和主成分分析。该系统通过数据收集与预处理、分词及结构化文本分析&#xff0c;为舆情监测、话题分析和用户行为研究提供了一体化的解决方案。 主要功能包括&a…

lkhgjfjghkbhjk

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…

LED驱动电路

LED驱动电路简介 摘要&#xff1a; LED照明是今年来快速兴起发展的一种新型光源&#xff0c;它的许多良好特点使得它的应用面越来越广。LED的单向导电特性使人一般认为应该用直流驱动&#xff0c;但是对直流恒压和限流的装置在保证比较好的限流特性时&#xff0c;自身功耗是很…

路政通 | OPENAIGC开发者大赛高校组AI创新之星奖

在第二届拯救者杯OPENAIGC开发者大赛中&#xff0c;涌现出一批技术突出、创意卓越的作品。为了让这些优秀项目被更多人看到&#xff0c;我们特意开设了优秀作品报道专栏&#xff0c;旨在展示其独特之处和开发者的精彩故事。 无论您是技术专家还是爱好者&#xff0c;希望能带给…

深圳某局联想SR850服务器黄灯 不开机维修

深圳 福田区1台Lenovo Thinksystem SR850 四路服务器黄灯问题现场处理。 1&#xff1a;型号&#xff1a;联想SR850 机架式2U服务器 2&#xff1a;故障&#xff1a;能通电&#xff0c;开机按钮快闪&#xff0c;随后叹号警告灯常亮 3&#xff1a;用户自行折腾无果后找到我们tech …

QT客户端发送HTTP请求此时服务器到底收到了哪些数据?

一个Http请求包括 请求行 请求头 空行 请求体 下面是示例&#xff1a; 1,2,3,4分别代表上面的四个部分&#xff0c;我只是做了一些解析&#xff0c;具体可以结合代码 1. post / HTTP/1.1 2.GET请求头包括Host(主机名),user-agent&#xff08;客户端标识符&#xff09;&am…

C++类和对象(中)【下篇】

&#x1f31f;个人主页&#xff1a;落叶 &#x1f31f;当前专栏: C专栏 目录 赋值运算符重载 运算符重载 赋值运算符重载 日期类实现 运算符重载<和运算符重载 运算符重载进行复用 运算符重载< 运算符重载> 运算符重载> 运算符重载! 获取某年某月的天数…

解决方案 | 镭速助力动漫游戏行业突破跨网文件交换瓶颈

在数字化浪潮推动下&#xff0c;动漫游戏行业蓬勃发展。随着高清技术的普及和云游戏的兴起&#xff0c;动漫游戏行业对动画的画质要求越来越高&#xff0c;数据量呈现爆炸式增长。然而&#xff0c;行业内的跨网文件交换难题也日益凸显&#xff0c;成为制约行业发展的瓶颈。 行业…

pyqt瀑布流布局

最近研究瀑布流布局&#xff0c;发现都是收费的&#xff0c;所以只能自己写算法写布局。 所以啥都不说直接上代码 ImageLabel 参考 pyqt5 QLabel显示网络图片或qfluentwidgets官网 代码 import math import sys from pathlib import Pathfrom PyQt5.Qt import * from qflue…

erlang学习:Linux命令学习4

顺序控制语句学习 if&#xff0c;else对文件操作 判断一个文件夹是否存在&#xff0c;如果存在则进行删除&#xff0c;如果不存在则创建该文件夹&#xff0c;并复制一份该脚本后&#xff0c;删除该脚本 if [ -d "/erlangtest/testdir"]; then echo "删除文件夹…

JavaWeb--小白笔记07-2:超链接以及servlet对表单数据的完整处理

一.超链接 Html使用标签<a></a>来设置超链接&#xff0c;<a>有一个属性href"" 必须加进去&#xff0c;里面就是链接地址 注意&#xff1a;链接里必须包含https://前缀 <a></a>里面可以是一个字&#xff0c;一个词或者一副图...点击…