EasyExcel實現圖片導出功能(記錄)

背景:在舊系統的基礎上,導出一些工單信息時,現需要新添加處理人的簽名或者簽章,這就涉及圖片的上傳、下載、寫入等幾個操作。

1、EasyExcel工具類

(1)支持下拉框的導出。

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com..common.handler.DropDownHandler;
import com..modules.device.convert.ImageCellWriteHandler;
import com..modules.device.domain.vo.DeviceAndTypeVO;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;@Slf4j
public class ExcelExportUtil {private static final String CHARACTER = "UTF-8";private static final String CONTENT_TYPE = "application/vnd.ms-excel;charset=utf-8";private static final String CONTENT_DISPOSITION = "Content-Disposition";private static final String CACHE_CONTROL = "Cache-Control";private static final String NO_STORE = "no-store";private static final String MAX_AGE = "max-age=0";private static final String PASSWORD = "excel_unlock";private static final Integer colSplit = 0;private static final Integer rowSplit = 1;private static final Integer leftmostColumn = 0;private static final Integer topRow = 1; 
/*** 通用導出 Excel 方法(支持下拉框和每行圖片插入)** @param response         HttpServletResponse* @param data             導出數據,數據行順序與 Excel 中順序一致(表頭在第0行,第一條數據為第1行)* @param clazz            數據模型 Class* @param fileName         導出文件名(不包含后綴)* @param dropDownHandler  下拉框處理器(可選,可傳 null)* @param imagesList       每條記錄對應的圖片數據列表,List中每個元素為 byte[2] 數組,*                         第0位為簽名圖片, 第1位為簽章圖片(可有可無)* @param signCol          簽名圖片插入列(0-based)* @param signatureCol     簽章圖片插入列(0-based)* @throws IOException     I/O 異常時拋出*/public static void exportExcel(HttpServletResponse response, List<?> data, Class<?> clazz, String fileName,Object dropDownHandler, List<byte[][]> imagesList,int signCol, int signatureCol) throws IOException {String fullFileName = fileName + ".xlsx";String encodedFileName = URLEncoder.encode(fullFileName, StandardCharsets.UTF_8.toString());response.setCharacterEncoding(CHARACTER);response.setContentType(CONTENT_TYPE);response.setHeader(CONTENT_DISPOSITION, "attachment; filename=" + encodedFileName);response.setHeader(CACHE_CONTROL, NO_STORE);response.addHeader(CACHE_CONTROL, MAX_AGE);ServletOutputStream out = null;ExcelWriter excelWriter = null;try {out = response.getOutputStream();ExcelWriterBuilder writerBuilder = EasyExcelFactory.write(out, clazz);// 注冊下拉框處理器(需確保 dropDownHandler 是 WriteHandler 類型)if (dropDownHandler != null && dropDownHandler instanceof WriteHandler) {writerBuilder.registerWriteHandler((WriteHandler) dropDownHandler);}excelWriter = writerBuilder.build();WriteSheet writeSheet = EasyExcelFactory.writerSheet(fileName).build();excelWriter.write(data, writeSheet);// 獲取 Workbook 和 SheetWorkbook workbook = excelWriter.writeContext().writeWorkbookHolder().getWorkbook();Sheet sheet = workbook.getSheetAt(0);// 遍歷數據行插入圖片(從第1行開始)if (imagesList != null && !imagesList.isEmpty()) {for (int i = 0; i < data.size(); i++) {int targetRowIndex = i + 1; // 數據行從第1行開始if (i < imagesList.size()) {byte[][] images = imagesList.get(i);if (images != null) {insertImages(sheet, workbook, targetRowIndex, images, signCol, signatureCol);}}}}// 必須顯式調用 finish 確保數據寫入流excelWriter.finish();out.flush();} catch (Exception e) {throw new IOException("導出 Excel 失敗: " + e.getMessage(), e);} finally {// 手動關閉資源(注意順序:先關閉 excelWriter,再關閉流)if (excelWriter != null) {excelWriter.finish(); // finish() 包含關閉操作}if (out != null) {try {out.close();} catch (IOException e) {log.error("關閉輸出流異常: ", e);}}}}/*** 通用的圖片插入方法,在指定的 Excel 行中插入簽名和簽章圖片** @param sheet         目標 Sheet* @param workbook      Excel Workbook* @param targetRow     目標行索引(0-based;表頭為0,第一條數據為1)* @param images        byte[2] 數組,其中 images[0] 為簽名圖片,images[1] 為簽章圖片* @param signCol       簽名圖片插入列(0-based)* @param signatureCol  簽章圖片插入列(0-based)*/private static void insertImages(Sheet sheet, Workbook workbook, int targetRow, byte[][] images,int signCol, int signatureCol) {if (sheet == null || workbook == null) {return;}Row row = sheet.getRow(targetRow);if (row == null) {row = sheet.createRow(targetRow);}Drawing<?> drawing = sheet.createDrawingPatriarch();if (images[0] != null && images[0].length > 0) {int pictureIdx = workbook.addPicture(images[0], Workbook.PICTURE_TYPE_PNG);ClientAnchor anchor = new XSSFClientAnchor(0, 0, 1023, 255, signCol, targetRow, signCol + 1, targetRow + 1);drawing.createPicture(anchor, pictureIdx);}if (images[1] != null && images[1].length > 0) {int pictureIdx = workbook.addPicture(images[1], Workbook.PICTURE_TYPE_PNG);ClientAnchor anchor = new XSSFClientAnchor(0, 0, 1023, 255, signatureCol, targetRow, signatureCol + 1, targetRow + 1);drawing.createPicture(anchor, pictureIdx);}}
}

(2)無下拉框實現

/*** 配合insertImages(Sheet sheet, Workbook workbook, byte[] signImage, byte[] signatureImage,*                                      int targetRowIndex, int signCol, int signatureCol) 方法使用* @param response* @param data* @param clazz* @param fileName* @param signImage* @param signatureImage* @param targetRow* @param signCol* @param signatureCol* @throws IOException*/public static void exportExcel(HttpServletResponse response, List<?> data, Class<?> clazz, String fileName,byte[] signImage, byte[] signatureImage,int targetRow, int signCol, int signatureCol) throws IOException {String encodedFileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");response.setCharacterEncoding("UTF-8");response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setHeader("Content-Disposition", "attachment; filename=" + encodedFileName);response.setHeader("Cache-Control", "no-store");response.addHeader("Cache-Control", "max-age=0");ExcelWriter excelWriter = null;ServletOutputStream out = null;try {out = response.getOutputStream();excelWriter = EasyExcelFactory.write(out, clazz).build();WriteSheet writeSheet = EasyExcelFactory.writerSheet(fileName).build();excelWriter.write(data, writeSheet);// 獲取 Workbook 和 SheetWorkbook workbook = excelWriter.writeContext().writeWorkbookHolder().getWorkbook();Sheet sheet = workbook.getSheetAt(0);// 插入圖片insertImages(sheet, workbook, signImage, signatureImage, targetRow, signCol, signatureCol);// 必須顯式調用 finish 確保寫入完成excelWriter.finish();out.flush();} finally {// 手動關閉資源(EasyExcel 3.x 中 finish() 已包含關閉操作)if (excelWriter != null) {excelWriter.finish(); // 確保資源釋放}if (out != null) {out.close();}}}/*** 通用inserImages方法,和沒有的DropDownHandler dropDownHandler參數的exportExcel方法一起配合使用* @param sheet* @param workbook* @param signImage* @param signatureImage* @param targetRowIndex* @param signCol* @param signatureCol*/private static void insertImages(Sheet sheet, Workbook workbook, byte[] signImage, byte[] signatureImage,int targetRowIndex, int signCol, int signatureCol) {if (sheet == null || workbook == null) {log.warn("插入圖片失敗: sheet 或 workbook 為空");return;}// 確保目標行存在Row row = sheet.getRow(targetRowIndex);if (row == null) {row = sheet.createRow(targetRowIndex);}Drawing<?> drawing = sheet.createDrawingPatriarch();// 插入簽名圖片if (signImage != null && signImage.length > 0) {int pictureIdx = workbook.addPicture(signImage, Workbook.PICTURE_TYPE_PNG);ClientAnchor anchor = new XSSFClientAnchor(0, 0, 1023, 255, signCol, targetRowIndex, signCol + 1, targetRowIndex + 1);drawing.createPicture(anchor, pictureIdx);}// 插入簽章圖片if (signatureImage != null && signatureImage.length > 0) {int pictureIdx = workbook.addPicture(signatureImage, Workbook.PICTURE_TYPE_PNG);ClientAnchor anchor = new XSSFClientAnchor(0, 0, 1023, 255, signatureCol, targetRowIndex, signatureCol + 1, targetRowIndex + 1);drawing.createPicture(anchor, pictureIdx);}}

2、實體類和自定義轉換類

//使用自定義轉換器,寫入空內容,但表頭顯示“簽名”@ExcelProperty(value = "處理人簽名", converter = ImageHeaderConverter.class, index = 15)private byte[] signImage;// 使用自定義轉換器,寫入空內容,但表頭顯示“簽名”@ExcelProperty(value = "處理人簽章", converter = ImageHeaderConverter.class, index = 16)private byte[] signatureImage;/*** 自定義Converter*/
public class ImageHeaderConverter implements Converter<byte[]> {@Overridepublic Class supportJavaTypeKey() {return byte[].class;}@Overridepublic WriteCellData<?> convertToExcelData(byte[] value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {// 返回空數據,防止自動轉換報錯,但表頭信息仍會根據@ExcelProperty的value顯示return new WriteCellData<>("");}@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return null;}public byte[] convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {return new byte[0];}
}

3、根據圖片路徑下載圖片工具類

public class ImagesUtils {public static byte[] downloadImage(String imageUrl) {if (imageUrl == null || imageUrl.trim().isEmpty()) {log.warn("下載圖片失敗: imageUrl 為空");return null;}HttpURLConnection connection = null;try {URL url = new URL(imageUrl);connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");connection.setConnectTimeout(10000);  // 增加超時時間到10秒connection.setReadTimeout(10000);connection.setInstanceFollowRedirects(true); // 允許自動重定向// 檢查 HTTP 響應碼int statusCode = connection.getResponseCode();if (statusCode != HttpURLConnection.HTTP_OK) {log.warn("下載圖片失敗: {},HTTP狀態碼: {},響應消息: {}",imageUrl, statusCode, connection.getResponseMessage());return null;}try (InputStream inputStream = connection.getInputStream();ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {byte[] buffer = new byte[4096];  // 增大緩沖區提升讀取效率int bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}return outputStream.toByteArray();}} catch (Exception e) {log.warn("下載圖片失敗: {},錯誤類型: {},詳細信息: {}",imageUrl, e.getClass().getSimpleName(), e.getMessage(), e); // 輸出完整異常return null;} finally {if (connection != null) {connection.disconnect(); // 顯式斷開連接}}}
}

4、業務邏輯實現

// 1. 查詢 Channel_SIGN_SIGNATURE 表,獲取所有處理記錄List<ChannelSignSignature> processList = channelSignSignatureMapper.selectList(new LambdaQueryWrapper<ChannelSignSignature>().in(ChannelSignSignature::getDisposeChannelId, ids));if (CollectionUtils.isEmpty(processList)) {return ReposeResult.failed(ResultCode.CHANNEL_EXPORT_NULL);}//根據前端傳入的ids順序排序處理記錄Map<Long, ChannelSignSignature> processMap = processList.stream().collect(Collectors.toMap(ChannelSignSignature::getDisposeChannelId, Function.identity()));List<ChannelSignSignature> sortedProcessList =  new ArrayList<>();for (Long id :ids) {if (!processMap.containsKey(id)) {return ReposeResult.failed("部分導出ID未保存處理記錄,請先處理記錄再導出");}sortedProcessList.add(processMap.get(id));}// 2. 獲取所有處理人姓名(保持原順序)List<String> userNames = sortedProcessList.stream().map(ChannelSignSignature::getChannelRecordName).collect(Collectors.toList());// 3. 批量查詢用戶信息(userId 映射表)Map<String, Long> userIdMap;if (CollectionUtils.isEmpty(userNames)) {userIdMap = new HashMap<>();} else {List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().in(User::getUsername, userNames));userIdMap = users.stream().collect(Collectors.toMap(User::getUsername, User::getId, (u1, u2) -> u1));}// 4. 查詢用戶簽名 & 簽章Map<Long, List<String>> signMap = new HashMap<>();Map<Long, List<String>> signatureMap = new HashMap<>();if (!userIdMap.isEmpty()) {// 4.1 批量查詢用戶簽名(userId -> 簽名列表)List<UserSign> userSigns = userSignMapper.selectList(new LambdaQueryWrapper<UserSign>().in(UserSign::getUserId, userIdMap.values()));signMap = userSigns.stream().collect(Collectors.groupingBy(UserSign::getUserId,LinkedHashMap::new,Collectors.mapping(UserSign::getContent, Collectors.toList())));// 4.2 批量查詢用戶簽章(userId -> 簽章列表)List<UserSignature> userSignatures = userSignatureMapper.selectList(new LambdaQueryWrapper<UserSignature>().in(UserSignature::getUserId, userIdMap.values()));signatureMap = userSignatures.stream().collect(Collectors.groupingBy(UserSignature::getUserId,LinkedHashMap::new,Collectors.mapping(UserSignature::getContent, Collectors.toList())));}Integer grading = UserUtils.getUser().getGrading();HashMap<Integer, String[]> dropDownMap = new HashMap<>();String[] results = Arrays.stream(ChannelResultEnum.values()).map(ChannelResultEnum::getDesc).toArray(String[]::new);dropDownMap.put(13, results);List<ChannelVO> channels = channelMapper.selectJoinList(ChannelVO.class, new MPJLambdaWrapper<>(DataChannel.class).selectAll(DataChannel.class).select(Dept::getDeptName).selectAs(Period::getDescription, "period").select(BenchInfo::getBench).selectCollection(MachineInfo.class, ChannelVO::getMachineInfos).leftJoin(ChannelModel.class, ChannelModel::getChannelId, DataChannel::getId).leftJoin(MachineInfo.class, MachineInfo::getId, ChannelModel::getModelId).leftJoin(Dept.class, Dept::getId, DataChannel::getDeptId).leftJoin(Period.class, Period::getId, DataChannel::getPeriodId).leftJoin(BenchInfo.class, BenchInfo::getId, DataChannel::getBenchId).ge(ObjectUtils.isNotEmpty(grading), DataChannel::getGrading, grading).in(DataChannel::getId, ids));channels.forEach(channelVO -> {List<String> models = channelVO.getMachineInfos().stream().map(MachineInfo::getModel).collect(Collectors.toList());channelVO.setModel(String.join(",", models));});//根據前端傳入的ids順序排序channelVOMap<Long, ChannelVO> channelVoMap= channels.stream().collect(Collectors.toMap(ChannelVO::getId, Function.identity()));List<ChannelVO> sortedChannelVOs = new ArrayList<>();for (Long id:ids) {if (!channelVoMap.containsKey(id)) {return ReposeResult.failed("部分導出ID未保存檢查記錄,請先保存處理記錄再導出");}sortedChannelVOs.add(channelVoMap.get(id));}List<ExportChannelDTO> exportChannelDTOS = CopyUtils.copyList(sortedChannelVOs, ExportChannelDTO.class);// 5. 按 `userNames` 生成 `signUrls` 和 `signatureUrls`(保證順序)List<String> signUrls = new ArrayList<>();List<String> signatureUrls = new ArrayList<>();for (String userName : userNames) {Long userId = userIdMap.get(userName);if (userId != null) {List<String> signs = signMap.getOrDefault(userId, Collections.emptyList());List<String> signatures = signatureMap.getOrDefault(userId, Collections.emptyList());// 如果有簽名,添加簽名;如果有簽章,添加簽章;如果都有,則都添加if (!signs.isEmpty()) {signUrls.addAll(signs);} else {signUrls.add(null);}if (!signatures.isEmpty()) {signatureUrls.addAll(signatures);} else {signatureUrls.add(null);}} else {// 處理人無簽名/簽章,則填充 nullsignUrls.add(null);signatureUrls.add(null);}}// 7. 賦值到 DTOfor (int i = 0; i <  exportChannelDTOS.size(); i++) {ExportChannelDTO dto =  exportChannelDTOS.get(i);// 取簽名圖片if (signUrls.get(i) != null) {dto.setSignImage(downloadImage(BASE_IMAGE_URL + signUrls.get(i)));} else {dto.setSignImage(null);}// 取簽章圖片if (signatureUrls.get(i) != null) {dto.setSignatureImage(downloadImage(BASE_IMAGE_URL + signatureUrls.get(i)));} else {dto.setSignatureImage(null);}}// 8. 構造圖片數據列表,與 checkDTOS 順序一致List<byte[][]> imagesList = exportChannelDTOS.stream().map(dto -> new byte[][]{dto.getSignImage() != null ? dto.getSignImage() : new byte[0],dto.getSignatureImage() != null ? dto.getSignatureImage() : new byte[0]}).collect(Collectors.toList());ExcelExportUtil.exportExcel(response,exportChannelDTOS,ExportChannelDTO.class,ConstantUtil.DATA_CHANNEL,new DropDownHandler(dropDownMap),imagesList,15,16);log.info("---導出數據通道信息完成---");         

代碼不可直接使用,只是自己記錄一下,方便下次使用,你完全可以使用AI來幫你寫這些部分。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75122.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75122.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75122.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android Material Design 3 主題配色終極指南:XML 與 Compose 全解析

最小必要顏色配置 <!-- res/values/themes.xml --> <style name"Theme.MyApp" parent"Theme.Material3.DayNight"><!-- 基礎三原色 --><item name"colorPrimary">color/purple_500</item><item name"col…

【Git】“warning: LF will be replaced by CRLF”的解決辦法

一、原因分析 不同操作系統的換行符標準不同&#xff1a; ? Windows&#xff1a;使用 CRLF&#xff08;\r\n&#xff09;表示換行&#xff1b; ? Linux/Mac&#xff1a;使用 LF&#xff08;\n&#xff09;表示換行 Git 檢測到本地文件的換行符與倉庫設置或目標平臺不兼容時…

PyTorch 深度學習實戰(33):聯邦學習與隱私保護

在上一篇文章中,我們探討了多模態學習與CLIP模型的應用。本文將深入介紹聯邦學習(Federated Learning)這一新興的分布式機器學習范式,它能夠在保護數據隱私的前提下實現多方協作的模型訓練。我們將使用PyTorch實現一個基礎的聯邦學習框架,并在圖像分類任務上進行驗證。 一…

藍橋杯 web 展開你的扇子(css3)

普通答案&#xff1a; #box:hover #item1{transform: rotate(-60deg); } #box:hover #item2{transform: rotate(-50deg); } #box:hover #item3{transform: rotate(-40deg); } #box:hover #item4{transform: rotate(-30deg); } #box:hover #item5{transform: rotate(-20deg); }…

LLM驅動的智能體:基于GPT的對話智能體開發指南

前言 大語言模型&#xff08;LLM, Large Language Model&#xff09;正在徹底改變智能體&#xff08;Agent&#xff09;的設計和實現方式。從簡單的聊天機器人到復雜的自動化助手&#xff0c;基于GPT等LLM的對話智能體已經在客服、教育、辦公自動化、編程助手等領域得到了廣泛…

深度解析 C# 中介者模式:設計與實戰應用

中介者模式&#xff08;Mediator Pattern&#xff09;是一種行為型設計模式&#xff0c;其核心思想是將多個對象之間的交互集中到一個中介者對象中&#xff0c;從而減少對象之間的直接交互&#xff0c;降低耦合度。在實現復雜系統時&#xff0c;中介者模式有助于提高系統的可維…

每日算法-250408

記錄今天解決的兩道 LeetCode 算法題&#xff0c;主要涉及二分查找的應用。 1283. 使結果不超過閾值的最小除數 題目描述 思路 核心思路是 二分查找。 解題過程 為什么可以使用二分&#xff1f; 關鍵在于單調性。對于一個固定的數組 nums&#xff0c;當除數 divisor 增大時&…

MySQL的子查詢

一、前言 MySQL 子查詢是指嵌套在其他 SQL 語句&#xff08;如 SELECT、WHERE、FROM 等&#xff09;內部的查詢。用于輔助主查詢完成復雜的數據篩選或計算。 二、子查詢分類 標量子查詢 描述&#xff1a;返回 單行單列&#xff08;一個值&#xff09;&#xff0c;常用于比較運…

Linux 基礎入門操作 前言 VIM的基本操作 2

1 VIM的背景介紹 Vi 的誕生與1976年&#xff0c;Vim 的前身是 Vi&#xff08;Visual Editor&#xff09;&#xff0c;由 Bill Joy 在 BSD Unix 系統上開發&#xff0c;作為 ed&#xff08;行編輯器&#xff09;的改進版本&#xff0c;提供全屏編輯功能&#xff0c;成為 Unix/L…

Java:Set操作

目錄 Set 轉 List Set 轉 List Set<String>set new HashSet<String>(); set.add("c"); set.add("d"); set.add("a"); set.add("a");//方法一&#xff1a; List<String>list new ArrayList<String>(set);//…

算力驅動未來:從邊緣計算到高階AI的算力革命

算力驅動未來&#xff1a;從邊緣計算到高階AI的算力革命 摘要 本文深入探討了不同算力水平&#xff08;20TOPS至160TOPS&#xff09;在人工智能領域的多樣化應用場景。從邊緣計算的實時目標檢測到自動駕駛的多傳感器融合&#xff0c;從自然語言處理的大模型應用到AI for Scie…

虛擬機上安裝openEuler和openGauss數據庫

1.虛擬機版本選擇VM 16 PRO 2.openEuler版本選擇openEuler-22.03-LTS-SP4-x86_64 下載地址&#xff1a;https://mirrors.aliyun.com/openeuler/openEuler-22.03-LTS-SP4/ISO/x86_64/openEuler-22.03-LTS-SP4-x86_64-dvd.iso 3.虛擬機安裝openEuler過程&#xff1a; 4.安裝ope…

0_Pytorch中的張量操作

[引言]張量的概念 1.基本概念 張量是一個通用的多維數組&#xff0c;可以表示標量&#xff08;0 維&#xff09;、向量&#xff08;1 維&#xff09;、矩陣&#xff08;2 維&#xff09;以及更高維度的數據。張量是 PyTorch 中的核心數據結構&#xff0c;用于表示和操作數據。…

LS-LINUX-002 簡易創建SSH

LS-LINUX-002 簡易創建SSH 1. CentOS 8 創建和配置SSH服務 1.1 安裝SSH服務 CentOS 8 默認已經安裝了OpenSSH服務。如果沒有安裝&#xff0c;可以使用以下命令安裝&#xff1a; sudo dnf install -y openssh-server1.2 啟動SSH服務 安裝完成后&#xff0c;需要啟動SSH服務…

計算機專業求職面試的常見題目分類整理

以下是計算機專業求職面試的常見題目分類整理&#xff0c;每個大類精選20道高頻問題&#xff0c;結合參考內容進行解析與擴展&#xff0c;幫助系統化備考&#xff1a; 一、數據結構與算法 解釋時間復雜度和空間復雜度 時間復雜度衡量算法執行時間隨輸入規模的增長趨勢&#xf…

腳本啟動 Java 程序

如果你想在后臺啟動一個 Java 程序&#xff0c;并在終端窗口中顯示一個自定義的名字&#xff0c;可以通過編寫一個簡單的腳本來實現。以下是一個基于 Linux/macOS 的解決方案&#xff0c;使用 Bash 腳本啟動 Java 程序&#xff0c;并在終端窗口中顯示自定義標題。 示例腳本 創建…

CentOS禁用nouveau驅動

1、驗證 nouveau 是否在運行 lsmod | grep nouveau如果命令返回結果&#xff0c;說明 nouveau 驅動正在運行。 2、編輯黑名單文件 通過編輯黑名單配置文件來禁用 nouveau 驅動&#xff0c;這樣在系統啟動時不會加載它。 vi /etc/modprobe.d/blacklist-nouveau.conf修改以下…

Linux: network: tcpdump: packets dropped by kernel

文章目錄 最近遇到一個問題原因libpcap/tcpdump 接口linux/libpcap 接口內核的處理原因可能有以下幾種:解決方法:man pcap_stats最近遇到一個問題 tcpdump命令顯示有dropped的包,而且是被內核drop的。 [root@-one-01 ~]# tcpdump -i any udp and port 8080 -v -w /root/udp…

WEB安全--提權思路

一、情形 在我們成功上傳webshell到服務器中并拿到權限時&#xff0c;發現我們的權限很低無法執行特定的命令&#xff0c;這時為了能做更多的操作&#xff0c;我們就需要提升權限。 二、方式 2.1、Windows提權 1、普通用戶執行systeminfo命令獲取服務器的基本信息&#xff0…

001 vue

https://cn.vuejs.org/ 文章目錄 v-bindv-modelv-on修飾符條件渲染/控制&#xff1a;v-if v-show列表渲染 M&#xff1a;即Model&#xff0c;模型&#xff0c;包括數據和一些基本操作 V&#xff1a;即View&#xff0c;視圖&#xff0c;頁面渲染結果 VM&#xff1a;即View-Mode…