在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    有了這個(gè)開(kāi)源工具后,我五點(diǎn)就下班了

    前言

    ??「一個(gè)優(yōu)秀的開(kāi)發(fā)者,一定是會(huì)利用各種工具來(lái)提升自己的開(kāi)發(fā)效率。」 前段時(shí)間,博主在Gitee/Github開(kāi)源了一個(gè)提升開(kāi)發(fā)效率的工具,工具內(nèi)集成了各種常用工具如csv、excel、ftp、文件系統(tǒng)等等,「只需要簡(jiǎn)單調(diào)用API,就可以得到想要的結(jié)果,可以極大幫助開(kāi)發(fā)者提升效率」,下面來(lái)一起看看這款工具如何使用吧。

    工具介紹

    ??報(bào)表的導(dǎo)出、導(dǎo)入功能、文件上傳、下載等在平常業(yè)務(wù)中是最常見(jiàn)不過(guò)的功能了,「許多小伙伴在開(kāi)發(fā)的時(shí)候才會(huì)去網(wǎng)上找之前別人編寫過(guò)的案例參考,但是許多博客記載的都是時(shí)間比較長(zhǎng)遠(yuǎn)或者不完整的代碼,這導(dǎo)致在引入的時(shí)候還要處理引入的許多未知問(wèn)題?!?/p>

    ??現(xiàn)在博主開(kāi)源的“輪子之王”包含了這些常見(jiàn)的功能,「源碼全開(kāi)發(fā),每種功能都有相應(yīng)的例子說(shuō)明,項(xiàng)目會(huì)持續(xù)更新迭代,有問(wèn)題還可以及時(shí)給項(xiàng)目提issue,相信比大多數(shù)網(wǎng)上的博客代碼可靠性更高。」

    ??「項(xiàng)目地址如下:」

    ??Github:https://github.com/it-learning-diary/it-wheels-king

    ??Gitee:https://gitee.com/it-learning-diary/it-wheels-king

    ??「項(xiàng)目結(jié)構(gòu)如下:」

    一、excel工具

    ??該工具實(shí)現(xiàn)采用的是開(kāi)源的easyexcel框架。easyexcel是阿里的開(kāi)發(fā)人員對(duì)poi框架進(jìn)行了優(yōu)化,解決了poi在大數(shù)據(jù)量時(shí)可能出現(xiàn)OOM異常,并且兼容xls和xlsx兩種文件類型的一個(gè)開(kāi)源框架。

    ??「excel工具集成功能如下:」

    • excel的導(dǎo)入(可以自定義轉(zhuǎn)換后的excel數(shù)據(jù)處理的業(yè)務(wù)邏輯,支持拋出異常、事務(wù)回滾、記錄解析時(shí)的異常數(shù)據(jù))
    • 導(dǎo)出(支持固定表頭,兼容多sheet頁(yè)和動(dòng)態(tài)表頭,兼容多sheet頁(yè))功能。

    ??「excel工具的特點(diǎn)如下:」

    ??使用過(guò)easyexcel框架的一些讀者知道,每個(gè)導(dǎo)入功能都要寫一個(gè)對(duì)應(yīng)的Listener進(jìn)行數(shù)據(jù)轉(zhuǎn)換,在很多時(shí)間其實(shí)轉(zhuǎn)換的邏輯都是類似的,不同的只不過(guò)是轉(zhuǎn)換后數(shù)據(jù)處理的業(yè)務(wù)邏輯不一樣。

    ??「本開(kāi)源項(xiàng)目的excel工具則利用Java中的泛型和Java8中的Consumer接口將相同的部分(轉(zhuǎn)換邏輯)抽取出來(lái),不同的部分則單獨(dú)傳入(數(shù)據(jù)處理的業(yè)務(wù)邏輯),這樣就避免了每個(gè)導(dǎo)入都需要?jiǎng)?chuàng)建一個(gè)相類似的Listerner,減少了類的創(chuàng)建和提高了開(kāi)發(fā)效率。」

    ??「部分源碼如下:」

    /** * 通用導(dǎo)入excel文件方法 * * @param fileStream 導(dǎo)入的文件流 * @param rowDto 接收excel每行數(shù)據(jù)的實(shí)體 * @param rowAction 將接收到的實(shí)體進(jìn)行自定義的業(yè)務(wù)處理邏輯方法 * @param實(shí)體類型 */public staticvoid importFile(InputStream fileStream, T rowDto, ThrowingConsumer rowAction) {// 獲取excel通用監(jiān)聽(tīng)器ExcelImportCommonListener commonListener = new ExcelImportCommonListener(rowAction);// 讀取excel文件并導(dǎo)入EasyExcel.read(fileStream, rowDto.getClass(), commonListener).sheet().doRead();}/** * excel文件導(dǎo)出(可以包含多個(gè)sheet頁(yè)),固定表頭(通過(guò)實(shí)體指定屬性的方式) * @param response * @param fileName 導(dǎo)出文件名 * @param head 導(dǎo)出表頭(多個(gè)sheet頁(yè)就是多個(gè)集合元素) * @param exportData 需要導(dǎo)出數(shù)據(jù) * @param sheetNames sheet頁(yè)的名稱,為空則默認(rèn)以:sheet + 數(shù)字規(guī)則命名 */public staticvoid exportFile(String fileName, List head, List exportData, List sheetNames, HttpServletResponse response) {if (Objects.isNull(response) || StrUtil.isBlank(fileName) || CollUtil.isEmpty(head)) {log.info(“ExcelExportUtil exportFile required param can’t be empty”);return;}ExcelWriter writer = null;try {response.setContentType(ExportConstant.EXCEL_CONTENT_TYPE);response.setCharacterEncoding(ExportConstant.UTF_8);response.setHeader(ExportConstant.CONTENT_DISPOSITION, ExportConstant.ATTACHMENT_FILENAME + fileName + ExportConstant.XLSX_SUFFIX);// 設(shè)置導(dǎo)出的表格樣式HorizontalCellStyleStrategy horizontalCellStyleStrategy = getExportDefaultStyle();writer = EasyExcel.write(response.getOutputStream()).registerWriteHandler(horizontalCellStyleStrategy).build();for (int itemIndex = 0; itemIndex < exportData.size(); itemIndex++) {// 表頭數(shù)據(jù)Object headData = head.get(itemIndex);// sheet頁(yè)的數(shù)據(jù)List list = exportData.get(itemIndex);WriteSheet sheet = EasyExcel.writerSheet(itemIndex, CollUtil.isEmpty(sheetNames) ? ExportConstant.SHEET_NAME + itemIndex + 1 : sheetNames.get(itemIndex)).head(headData.getClass()).build();writer.write(list, sheet);}} catch (Exception e) {log.error("ExcelExportUtil exportFile in error:{}", e);} finally {if (null != writer) {writer.finish();}}}

    ??「使用案例如下(在工具中每個(gè)項(xiàng)目都有具體的案例,不懂的還可以留言跟博主溝通):」

    /** * 導(dǎo)入用戶數(shù)據(jù)案例 * * @param file */@Transactional(rollbackFor = Exception.class)public void uploadUserListDemoWithExcel(MultipartFile file, String username) throws Exception {// 此處先校驗(yàn)導(dǎo)入的文件類型是否為excelString type = FileTypeUtil.getType(file.getInputStream());if (StrUtil.isBlank(type) || type.contains(ImportConstant.XLS_TYPE) || type.contains(ImportConstant.XLSX_TYPE)) {// 返回校驗(yàn)失敗信息return;}User user = new User();user.setId(100);user.setName(“外層”);user.setPassword(“外層”);userService.save(user);// 調(diào)用統(tǒng)一導(dǎo)入方法ExcelImportUtil.importFile(file.getInputStream(), new UserDto(), UserServiceImpl::saveUserList);} /** * 導(dǎo)出案例 * * @param response */public void exportUserListDemoWithExcel(HttpServletResponse response) {// 表頭(使用excel中的注解定義,如果表頭不固定,請(qǐng)使用ExcelExportUtil.exportWithDynamicData進(jìn)行導(dǎo)出)List head = Stream.of(new UserExportVo()).collect(Collectors.toList());// 數(shù)據(jù)(使用兩層list為了兼容多個(gè)sheet頁(yè),如果是不同的sheet頁(yè)則放在不同的List集合中)List exportDataList = new ArrayList();List exportItem = new ArrayList();// 查詢數(shù)據(jù)List dbData = userService.list();// 將數(shù)據(jù)轉(zhuǎn)換成導(dǎo)出需要的實(shí)際數(shù)據(jù)格式,此處只是演示for (User user : dbData) {UserExportVo vo = new UserExportVo();BeanUtil.copyProperties(user, vo);exportItem.add(vo);}exportDataList.add(exportItem);// sheet頁(yè)名稱-自定義,如果沒(méi)有則傳空List sheetNameList = Stream.of(“sheet1”).collect(Collectors.toList());ExcelExportUtil.exportFile(“user”, head, exportDataList, sheetNameList, response);}

    二、csv工具

    ??Csv即逗號(hào)分隔值,也可以稱為字符分隔符,「與excel等文件相比,excel文件中會(huì)包含許多格式信息,占用的空間會(huì)更大,所以Csv在很多大數(shù)據(jù)場(chǎng)景導(dǎo)出、導(dǎo)入場(chǎng)景是非常常見(jiàn)的。該工具實(shí)現(xiàn)采用的是開(kāi)源的univocity-parsers框架實(shí)現(xiàn)。」

    ??之前有一篇專門講解輪子之王項(xiàng)目為何使用univocity-parsers框架集成csv的詳細(xì)過(guò)程,有興趣的讀者可以點(diǎn)擊鏈接查看:集成csv工具的前因后果

    ??「部分源碼如下:」

    /** * 使用實(shí)體bean接收csv數(shù)據(jù)文件并進(jìn)行數(shù)據(jù)落盤 * * @param inputStream * @param errorList * @param rowDtoClass * @param rowAction * @param*/public staticvoid importCsvWithBean(InputStream inputStream, List errorList, Class rowDtoClass, ThrowingConsumer rowAction) {// 定義bean解析者:用于將csv中數(shù)據(jù)綁定到實(shí)體屬性中,然后存儲(chǔ)帶list集合上BeanListProcessor rowProcessor = new BeanListProcessor(rowDtoClass);CsvParserSettings setting = getDefaultSetting(errorList);setting.setProcessor(rowProcessor);// 創(chuàng)建csv文件解析CsvParser csvParser = new CsvParser(setting);csvParser.parse(inputStream);// 獲取數(shù)據(jù)映射后的集合List dataList = rowProcessor.getBeans();// 校驗(yàn)必填字段for (T row : dataList) {// 校驗(yàn)導(dǎo)入字段ImportValid.validRequireField(row, errorList);}// 執(zhí)行數(shù)據(jù)持久化persistentBeanDataToDb(dataList, rowAction);} /** * 導(dǎo)出csv文件(表頭和行都以實(shí)體的方式) * * @param response * @param head * @param rowDataList */public staticvoid exportCsvWithBean(HttpServletResponse response, String fileName, T head, List rowDataList) {CsvWriter writer = null;try {// 設(shè)置響應(yīng)頭格式response.setContentType(ExportConstant.EXCEL_CONTENT_TYPE);response.setCharacterEncoding(ExportConstant.UTF_8);response.setHeader(ExportConstant.CONTENT_DISPOSITION, ExportConstant.ATTACHMENT_FILENAME + fileName + ExportConstant.CSV_SUFFIX);// 設(shè)置導(dǎo)出格式CsvWriterSettings setting = getDefaultWriteSetting();// 創(chuàng)見(jiàn)bean處理器,用于處理寫入數(shù)據(jù)BeanWriterProcessor beanWriter = new BeanWriterProcessor(head.getClass());setting.setRowWriterProcessor(beanWriter);// 導(dǎo)出數(shù)據(jù)writer = new CsvWriter(response.getOutputStream(), setting);writer.processRecords(rowDataList);writer.flush();} catch (Exception e) {log.error(“CsvExportUtil exportCsvWithBean in error:{}”, e);} finally {if (Objects.nonNull(writer)) {writer.close();}}}

    ??「使用案例如下:」

    /** * 導(dǎo)出案例 * * @param response */public void exportUserListWithCsv(HttpServletResponse response) {List exportItem = new ArrayList();// 查詢數(shù)據(jù)List dbData = userService.list();// 使用字符串?dāng)?shù)組方式作為表頭導(dǎo)出csv數(shù)據(jù)List head = Stream.of(“id”, “name”, “password”).collect(Collectors.toList());List dataList = new ArrayList();for (User user : dbData) {List row = new ArrayList();row.add(user.getId());row.add(user.getName());row.add(user.getPassword());dataList.add(row);}CsvExportUtil.exportCsvWithString(response, “demo”, head, dataList);} /** * 導(dǎo)入用戶數(shù)據(jù)案例(csv模式) * * @param file */@Transactional(rollbackFor = Exception.class)public void uploadUserListWithCsv(MultipartFile file) throws Exception {// 此處先校驗(yàn)導(dǎo)入的文件類型是否為csvString type = FileTypeUtil.getType(file.getInputStream());if (StrUtil.isBlank(type) || type.contains(ImportConstant.CSV_TYPE)) {// 返回校驗(yàn)失敗信息return;}User user = new User();user.setId(100);user.setName(“外層”);user.setPassword(“外層”);userService.save(user);List errorLogList = new ArrayList();// 調(diào)用統(tǒng)一導(dǎo)入方法// 方式一:使用csv數(shù)據(jù)映射到dto實(shí)體的方式進(jìn)行數(shù)據(jù)導(dǎo)入//CsvImportUtil.importCsvWithBean(file.getInputStream(), errorLogList, UserCsvDto.class, UserServiceImpl::saveUserListWithCsv);// 方式二、使用csv數(shù)據(jù)映射到字符串?dāng)?shù)組的方式進(jìn)行數(shù)據(jù)導(dǎo)入CsvImportUtil.importCsvWithString(file.getInputStream(), errorLogList, UserCsvDto.class, UserServiceImpl::saveUserListWithCsvStringArrDemo);// 如果存在解析異常,輸出解析異常并進(jìn)行事務(wù)回滾if (CollUtil.isNotEmpty(errorLogList)) {throw new RuntimeException(StrUtil.toString(errorLogList));}}

    三、ftp工具

    ??Ftp文件上傳下載相比excel、csv等出現(xiàn)的場(chǎng)景較少,「但是,如果你參與的項(xiàng)目是政府或者涉及到第三方舊系統(tǒng)對(duì)接的時(shí)候,很多時(shí)候就需要使用到它。因?yàn)楹芏嗯f系統(tǒng)或者政府項(xiàng)目使用的技術(shù)比較舊或者有制度限制,一般都是以文件的形式與你進(jìn)行交互,此時(shí)ftp工具就很有效了?!?/p>

    ??Ftp工具使用的commons-net開(kāi)源框架進(jìn)行實(shí)現(xiàn),具體的集成流程之前單獨(dú)使用一篇文章進(jìn)行了非常詳細(xì)的介紹,有需要的讀者可以點(diǎn)擊后面鏈接查看:手把手教你搭建ftp服務(wù)器,并用程序完成ftp上傳下載功能

    ??「部分源碼如下:」

    /** * 上傳 * * @return */public boolean upload(FtpUploadParam param) {boolean flag = false;FTPClient ftpClient = new FTPClient();//1 測(cè)試連接if (connect(ftpClient, param.getHostname(), param.getPort(), param.getUsername(), param.getPassword())) {try {//2 檢查工作目錄是否存在,不存在則創(chuàng)建if (!ftpClient.changeWorkingDirectory(param.getWorkingPath())) {ftpClient.makeDirectory(param.getWorkingPath());}// 將文件編碼成Ftp服務(wù)器支持的編碼類型(FTP協(xié)議里面,規(guī)定文件名編碼為iso-8859-1,所以目錄名或文件名需要轉(zhuǎn)碼。)String fileName = new String(param.getSaveName().getBytes(ftpClientCharset), ftpServerCharset);// 3 上傳文件if (ftpClient.storeFile(fileName, param.getInputStream())) {flag = true;} else {log.warn(“FtpUtils uploadFile unsuccessfully!!”);}} catch (IOException e) {log.error(“FtpUtils upload in error:{}”, e);} finally {disconnect(ftpClient);}}return flag;}/** * @description: 下載ftp文件 * @param: * @param: param * @param: downloadFileName * @return: * @date: 2022/7/14 10:56 */public boolean download(FtpDownloadParam param, String downloadFileName) {FTPClient ftpClient = new FTPClient();FileOutputStream out = null;boolean downloadResult = false;//1 測(cè)試連接if (connect(ftpClient, param.getHostname(), param.getPort(), param.getUsername(), param.getPassword())) {try {String localPath = param.getDownloadPath() + param.getFileName();out = new FileOutputStream(new File(localPath));//2 檢查工作目錄是否存在,不存在返回// if (!ftpClient.changeWorkingDirectory(param.getWorkingPath())) {//return false;// }/* * 打開(kāi)FTP服務(wù)器的PASS模式(不記得FTP協(xié)議支持的模式請(qǐng)翻到文章第一階段) * 這個(gè)方法的意思就是每次數(shù)據(jù)連接之前,ftp client告訴ftp server開(kāi)通一個(gè)端口來(lái)傳輸數(shù)據(jù). 因?yàn)閒tp * server可能每次開(kāi)啟不同的端口來(lái)傳輸數(shù)據(jù),但是在linux上,由于安全限制,可能某些端口沒(méi)有開(kāi)啟,可能出現(xiàn)出現(xiàn)阻塞 */ftpClient.enterLocalPassiveMode();// 設(shè)置文件的傳輸方式-二進(jìn)制ftpClient.setFileType(FTP.BINARY_FILE_TYPE);// 將文件編碼成Ftp服務(wù)器支持的編碼類型(FTP協(xié)議里面,規(guī)定文件名編碼為iso-8859-1,所以目錄名或文件名需要轉(zhuǎn)碼。)// 缺少編碼轉(zhuǎn)換會(huì)導(dǎo)致:從FTP服務(wù)器下載下來(lái)的文件是破損的,無(wú)法被打開(kāi)downloadResult = ftpClient.retrieveFile(new String(downloadFileName.getBytes(ftpClientCharset), ftpServerCharset), out);out.flush();} catch (IOException e) {log.error(“FtpUtils upload in error:{}”, e);return false;} finally {try {if (Objects.nonNull(out)) {out.close();}} catch (Exception e) {log.error(“FtpUtils upload in error:{}”, e);}disconnect(ftpClient);}}return downloadResult;}

    ??「具體使用案例如下:」

    @PostMapping(“/ftp/upload”)public void upload() {try {FtpUploadParam param = new FtpUploadParam();param.setHostname(ftpConfig.getServerHostname());param.setPort(ftpConfig.getServerPort());param.setUsername(ftpConfig.getServerUsername());param.setPassword(ftpConfig.getServerPassword());param.setWorkingPath(ftpConfig.getServerWorkingPath());param.setSaveName(“xxx.mp3”);InputStream in = new FileInputStream(new File(“D:/uploadfile/like.mp3”));param.setInputStream(in);ftpUtils.upload(param);} catch (Exception e) {log.error(“TestFtpServerController upload 錯(cuò)誤:{}”, e);}}@PostMapping(“/ftp/download”)public void download() {try {FtpDownloadParam param = new FtpDownloadParam();param.setHostname(ftpConfig.getServerHostname());param.setPort(ftpConfig.getServerPort());param.setUsername(ftpConfig.getServerUsername());param.setPassword(ftpConfig.getServerPassword());param.setWorkingPath(ftpConfig.getServerWorkingPath());param.setDownloadPath(“D:/downloadFile/”);param.setFileName(“xxx.mp3”);ftpUtils.download(param, “xxxx.mp3”);} catch (Exception e) {log.error(“TestFtpServerController download 錯(cuò)誤:{}”, e);}}

    三、分布式文件系統(tǒng)工具

    ??「非結(jié)構(gòu)化數(shù)據(jù)通常是使用文件的方式進(jìn)行存儲(chǔ),這時(shí)候不可避免地要使用到文件系統(tǒng)進(jìn)行管理?!?分布式文件系統(tǒng)工具使用了第三方開(kāi)源框架seaweedfs進(jìn)行搭建,可以實(shí)現(xiàn)程序上傳,刪除、下載、查詢,并有文件分布式存儲(chǔ),避免單點(diǎn)故障,節(jié)約成本等特點(diǎn)。

    ??前面也專門通過(guò)一篇文章講解了:為何要使用seaweedfs框架搭建分布式文件系統(tǒng)的,感興趣的讀者可以通過(guò)下方鏈接進(jìn)行查看:Gitee圖床崩潰后,我使用Seaweedfs搭建了文件系統(tǒng)并封裝成輪子開(kāi)源

    ??「部分源碼如下:」

    /** * @description: 上傳單個(gè)文件到文件服務(wù)器 * @param: file * @return: 文件的fid + 文件的請(qǐng)全訪問(wèn)地址 * @author: it */public String uploadFile(MultipartFile file) throws Exception {FileSource fileSource = getFileSource();FileTemplate fileTemplate = new FileTemplate(fileSource.getConnection());// 上傳文件FileHandleStatus handleStatus = fileTemplate.saveFileByStream(file.getOriginalFilename(), file.getInputStream(), contentType);// 獲取上傳文件的訪問(wèn)地址String fileUrl = fileTemplate.getFileUrl(handleStatus.getFileId());// 關(guān)閉當(dāng)前連接fileSource.shutdown();return handleStatus.getFileId() + StrUtil.DASHED + fileUrl;}/** * @description: 根據(jù)文件下載文件 * @param: fid * @param: response * @param: fileName * @author: it */public void downloadFileByFid(HttpServletResponse response, HttpServletRequest request, String fid, String fileName) throws Exception {FileSource fileSource = getFileSource();FileTemplate fileTemplate = new FileTemplate(fileSource.getConnection());StreamResponse fileStream = fileTemplate.getFileStream(fid);// 設(shè)置響應(yīng)頭response.setContentType(CommonConstant.CONTENT_TYPE);response.setCharacterEncoding(CommonConstant.UTF_8);String encodeFileName = buildingFileNameAdapterBrowser(request, fileName);response.setHeader(CommonConstant.CONTENT_DISPOSITION, CommonConstant.ATTACHMENT_FILENAME + encodeFileName);// 讀取并寫入到響應(yīng)輸出InputStream inputStream = fileStream.getInputStream();byte[] fileByte = new byte[inputStream.available()];inputStream.read(fileByte);response.getOutputStream().write(fileByte);response.getOutputStream().flush();fileSource.shutdown();}

    ??「具體使用案例如下:」

    /** * @description: 上傳文件 * @param: * @param: file * @return: * @author: it * @date: 2022/7/14 17:01 */@ResponseBody@RequestMapping(“upload”)public void uploadFile(MultipartFile file) {try {String fileUrl = seaweedFsUtil.uploadFile(file);System.out.println(fileUrl);} catch (Exception e) {log.error(“TestSeaweedFsController uploadFile in error:{}”, e);}}/** * @description: 下載文件 * @param: * @param: fileId * @return: * @author: it * @date: 2022/7/14 17:01 */@RequestMapping(“download”)public void downloadFile(HttpServletResponse response, HttpServletRequest request, String fileId, String fileName) {try {seaweedFsUtil.downloadFileByFid(response, request, fileId, fileName);} catch (Exception e) {log.error(“TestSeaweedFsController downloadFile in error:{}”, e);}}

    工具更新

    ??到此為止,輪子之王已集成的工具就介紹完畢了,后續(xù)還會(huì)不斷更新、集成新的輪子,下面給大家介紹一下下一段時(shí)間項(xiàng)目的一些工作(「如果讀者有想要集成的輪子,歡迎提issue或者這文章下面留言」):

    • 集成一個(gè)可視化界面,更好地介紹開(kāi)源工具中各個(gè)輪子的引入案例,方便大家使用。
    • 集成word文件導(dǎo)出工具
    • 集成pdf文件導(dǎo)出工具
    • 集成復(fù)雜報(bào)表的報(bào)表導(dǎo)出工具(使用freemaker框架)
    • 待更新…

    集成方案介紹關(guān)聯(lián)文章

    • 手把手教你搭建ftp服務(wù)器,并用程序完成ftp上傳下載功能
    • 集成csv工具的前因后果
    • Gitee圖床崩潰后,我使用Seaweedfs搭建了文件系統(tǒng)并封裝成輪子開(kāi)源

    寫在最后

    ??開(kāi)源之路不容易,開(kāi)源之心不忘記!「如果博主開(kāi)源的項(xiàng)目對(duì)您有所幫助,請(qǐng)給項(xiàng)目star,給博主更多動(dòng)力,如果閱讀文章給您有所幫助,請(qǐng)給博主點(diǎn)贊、關(guān)注?!?/p>

    ??該開(kāi)源項(xiàng)目會(huì)持續(xù)更新和維護(hù),希望有更多讀者能夠提出建議和想法,「如果有需要集成的工具,歡迎給項(xiàng)目提issue或者這文章下面留言,博主看到后會(huì)及時(shí)回復(fù)?!?/p>

    鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場(chǎng),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系管理員(admin#wlmqw.com)刪除。
    用戶投稿
    上一篇 2022年9月25日 09:11
    下一篇 2022年9月25日 09:11

    相關(guān)推薦

    • 什么是推廣cpa一篇文章帶你看懂CPA推廣渠道

      CPA渠道 CPA指的是按照指定的行為結(jié)算,可以是搜索,可以是注冊(cè),可以是激活,可以是搜索下載激活,可以是綁卡,實(shí)名認(rèn)證,可以是付費(fèi),可以是瀏覽等等。甲乙雙方可以根據(jù)自己的情況來(lái)定…

      2022年11月25日
    • 抖音直播帶貨有哪些方法技巧(抖音直播帶貨有哪些痛點(diǎn))

      如今抖音這個(gè)短視頻的變現(xiàn)能力越來(lái)越突顯了,尤其是在平臺(tái)上開(kāi)通直播,更具有超強(qiáng)的帶貨屬性,已經(jīng)有越來(lái)越多的普通人加入到其中了。不過(guò)直播帶貨雖然很火,但是也不是每個(gè)人都能做好的,那么在…

      2022年11月24日
    • 科比19歲女兒遭自稱與她生“科比式孩子”男子跟蹤騷擾

      極目新聞?dòng)浾咄趿亮咙S佳琪 據(jù)??怂剐侣劸W(wǎng)報(bào)道,當(dāng)?shù)貢r(shí)間11月21日,已故籃球巨星科比·布萊恩特的長(zhǎng)女娜塔莉亞·布萊恩特21日向法院提交臨時(shí)限制令,聲稱這位32歲的前科從十幾歲起就騷…

      2022年11月24日
    • 免費(fèi)清理c盤的軟件(清理c盤空間不影響系統(tǒng))

      電腦用久了慢如龜速,還卡頓,這最大的原因啊就是C盤空間不足造成的。 即使電腦配置再好,或者硬盤再快,如果長(zhǎng)時(shí)間沒(méi)有打掃C盤,打開(kāi)文件或者穩(wěn)定之類的,都卡得讓人頭大。 這時(shí)候呢不要去…

      2022年11月24日
    • 明查|美國(guó)新冠后遺癥患者中有16%癥狀嚴(yán)重以致無(wú)法工作?

      點(diǎn)擊進(jìn)入澎湃新聞全球事實(shí)核查平臺(tái) 速覽 – 網(wǎng)傳數(shù)據(jù)比例無(wú)權(quán)威信源佐證,該比例有可能是結(jié)合了美國(guó)疾病防控中心和布魯金斯學(xué)會(huì)的數(shù)據(jù)得出,但這兩個(gè)機(jī)構(gòu)的調(diào)研目的和樣本都不同…

      2022年11月24日
    • pdf虛擬打印機(jī)(添加pdf虛擬打印機(jī))

      本文主要講的是pdf虛擬打印機(jī),以及和添加pdf虛擬打印機(jī)相關(guān)的知識(shí),如果覺(jué)得本文對(duì)您有所幫助,不要忘了將本文分享給朋友。 pdf虛擬打印機(jī)具體是什么功能? 電腦虛擬打印機(jī)的功能有…

      2022年11月24日
    • 分享2大類微信引流軟件(不花錢的微信引流軟件都有哪些)

      不花錢的微信引流軟件之前介紹了不少節(jié)省社群運(yùn)營(yíng)精力、提高社群運(yùn)營(yíng)效率的方法,今天主要給大家推薦一些簡(jiǎn)單好用的工具。 大家首先要掌握尋找工具的方法,因?yàn)楣ぞ呖赡芤驗(yàn)槠脚_(tái)封禁等原因不能…

      2022年11月22日
    • 高德地圖無(wú)網(wǎng)絡(luò)可以導(dǎo)航嗎 高德地圖怎么離線導(dǎo)航

      高德地圖是現(xiàn)在大家比較常用的一個(gè)導(dǎo)航軟件,很多朋友在使用中都存在著一個(gè)疑惑,那就是在沒(méi)有網(wǎng)絡(luò)的時(shí)候該怎么導(dǎo)航呢?現(xiàn)在就讓小編帶大家來(lái)看一下吧。 1.首先打開(kāi)進(jìn)入高德地圖頁(yè)面,然后點(diǎn)…

      2022年11月21日
    • ftp端口號(hào)(ftp端口號(hào)可以自定義嗎)

      FTP端口號(hào)是21在FTP服務(wù)器中,我們往往會(huì)給不同的部門或者某個(gè)特定的用戶設(shè)置一個(gè)帳戶但是,這個(gè)賬戶有個(gè)特點(diǎn),就是其只能夠訪問(wèn)自己的主目錄服務(wù)器通過(guò)這種方式來(lái)保障FTP服務(wù)上其他…

      2022年11月21日
    • 淘寶運(yùn)營(yíng)數(shù)據(jù)分析的3個(gè)指標(biāo)解析(運(yùn)營(yíng)數(shù)據(jù)分析怎么做)

      我們知道淘寶運(yùn)營(yíng)工作中對(duì)于數(shù)據(jù)的分析與整理是很重要的,這些工作乍一聽(tīng)可能比較難,但是也有一些相關(guān)的技巧可以讓我們能夠有效的找出對(duì)我們有用的數(shù)據(jù),這樣我們也能夠更加直觀的看出我們店鋪…

      2022年11月20日

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息