您当前的位置:首页 > 电脑百科 > 程序开发 > 开源程序 > 百科

有了这个开源工具后,我五点就下班了

时间:2022-08-09 13:47:18  来源:  作者:IT学习日记

前言

  「一个优秀的开发者,一定是会利用各种工具来提升自己的开发效率。」 前段时间,博主在Gitee/Github开源了一个提升开发效率的工具,工具内集成了各种常用工具如csv、Excel、ftp、文件系统等等,「只需要简单调用API,就可以得到想要的结果,可以极大帮助开发者提升效率」,下面来一起看看这款工具如何使用吧。

 

工具介绍

  报表的导出、导入功能、文件上传、下载等在平常业务中是最常见不过的功能了,「许多小伙伴在开发的时候才会去网上找之前别人编写过的案例参考,但是许多博客记载的都是时间比较长远或者不完整的代码,这导致在引入的时候还要处理引入的许多未知问题。」

  现在博主开源的“轮子之王”包含了这些常见的功能,「源码全开发,每种功能都有相应的例子说明,项目会持续更新迭代,有问题还可以及时给项目提issue,相信比大多数网上的博客代码可靠性更高。」

  「项目地址如下:」

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

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

  「项目结构如下:」

 

一、excel工具

  该工具实现采用的是开源的easyexcel框架。easyexcel是阿里的开发人员对poi框架进行了优化,解决了poi在大数据量时可能出现OOM异常,并且兼容xls和xlsx两种文件类型的一个开源框架。

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

  • excel的导入(可以自定义转换后的excel数据处理的业务逻辑,支持抛出异常、事务回滚、记录解析时的异常数据)
  • 导出(支持固定表头,兼容多sheet页和动态表头,兼容多sheet页)功能。

  「excel工具的特点如下:」

  使用过easyexcel框架的一些读者知道,每个导入功能都要写一个对应的Listener进行数据转换,在很多时间其实转换的逻辑都是类似的,不同的只不过是转换后数据处理的业务逻辑不一样。

  「本开源项目的excel工具则利用JAVA中的泛型和Java8中的Consumer接口将相同的部分(转换逻辑)抽取出来,不同的部分则单独传入(数据处理的业务逻辑),这样就避免了每个导入都需要创建一个相类似的Listerner,减少了类的创建和提高了开发效率。」

  「部分源码如下:」

 /**     * 通用导入excel文件方法     *     * @param fileStream 导入的文件流     * @param rowDto 接收excel每行数据的实体     * @param rowAction 将接收到的实体进行自定义的业务处理逻辑方法     * @param <T> 实体类型     */    public static <T> void importFile(InputStream fileStream, T rowDto, ThrowingConsumer<List<T>> rowAction) {        // 获取excel通用监听器        ExcelImportCommonListener<T> commonListener = new ExcelImportCommonListener<>(rowAction);        // 读取excel文件并导入        EasyExcel.read(fileStream, rowDto.getClass(), commonListener).sheet().doRead();    }    /**     * excel文件导出(可以包含多个sheet页),固定表头(通过实体指定属性的方式)     * @param response     * @param fileName   导出文件名     * @param head       导出表头(多个sheet页就是多个集合元素)     * @param exportData 需要导出数据     * @param sheetNames sheet页的名称,为空则默认以:sheet + 数字规则命名     */    public static <T> void exportFile(String fileName, List<T> head, List<List<T>> exportData, List<String> 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);            // 设置导出的表格样式            HorizontalCellStyleStrategy horizontalCellStyleStrategy = getExportDefaultStyle();            writer = EasyExcel.write(response.getOutputStream()).registerWriteHandler(horizontalCellStyleStrategy).build();            for (int itemIndex = 0; itemIndex < exportData.size(); itemIndex++) {                // 表头数据                Object headData = head.get(itemIndex);                // sheet页的数据                List<T> 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();            }        }    }

  「使用案例如下(在工具中每个项目都有具体的案例,不懂的还可以留言跟博主沟通):」

/**     * 导入用户数据案例     *     * @param file     */    @Transactional(rollbackFor = Exception.class)    public void uploadUserListDemoWithExcel(MultipartFile file, String username) throws Exception {        // 此处先校验导入的文件类型是否为excel        String type = FileTypeUtil.getType(file.getInputStream());        if (StrUtil.isBlank(type) || type.contAIns(ImportConstant.XLS_TYPE) || type.contains(ImportConstant.XLSX_TYPE)) {            // 返回校验失败信息            return;        }        User user = new User();        user.setId(100);        user.setName("外层");        user.setPassword("外层");        userService.save(user);        // 调用统一导入方法        ExcelImportUtil.importFile(file.getInputStream(), new UserDto(), UserServiceImpl::saveUserList);    } /**     * 导出案例     *     * @param response     */    public void exportUserListDemoWithExcel(HttpServletResponse response) {        // 表头(使用excel中的注解定义,如果表头不固定,请使用ExcelExportUtil.exportWithDynamicData进行导出)        List<UserExportVo> head = Stream.of(new UserExportVo()).collect(Collectors.toList());        // 数据(使用两层list为了兼容多个sheet页,如果是不同的sheet页则放在不同的List集合中)        List<List<UserExportVo>> exportDataList = new ArrayList<>();        List<UserExportVo> exportItem = new ArrayList<>();        // 查询数据        List<User> dbData = userService.list();        // 将数据转换成导出需要的实际数据格式,此处只是演示        for (User user : dbData) {            UserExportVo vo = new UserExportVo();            BeanUtil.copyProperties(user, vo);            exportItem.add(vo);        }        exportDataList.add(exportItem);        // sheet页名称-自定义,如果没有则传空        List<String> sheetNameList = Stream.of("sheet1").collect(Collectors.toList());        ExcelExportUtil.exportFile("user", head, exportDataList, sheetNameList, response);    }

二、csv工具

  Csv即逗号分隔值,也可以称为字符分隔符,「与excel等文件相比,excel文件中会包含许多格式信息,占用的空间会更大,所以Csv在很多大数据场景导出、导入场景是非常常见的。该工具实现采用的是开源的univocity-parsers框架实现。」

  之前有一篇专门讲解轮子之王项目为何使用univocity-parsers框架集成csv的详细过程,有兴趣的读者可以点击链接查看:集成csv工具的前因后果

  「部分源码如下:」

 /**     * 使用实体bean接收csv数据文件并进行数据落盘     *     * @param inputStream     * @param errorList     * @param rowDtoClass     * @param rowAction     * @param <T>     */    public static <T> void importCsvWithBean(InputStream inputStream, List<String> errorList, Class rowDtoClass, ThrowingConsumer<List<T>> rowAction) {        // 定义bean解析者:用于将csv中数据绑定到实体属性中,然后存储带list集合上        BeanListProcessor<T> rowProcessor = new BeanListProcessor<>(rowDtoClass);        CsvParserSettings setting = getDefaultSetting(errorList);        setting.setProcessor(rowProcessor);        // 创建csv文件解析        CsvParser csvParser = new CsvParser(setting);        csvParser.parse(inputStream);        // 获取数据映射后的集合        List<T> dataList = rowProcessor.getBeans();        // 校验必填字段        for (T row : dataList) {            // 校验导入字段            ImportValid.validRequireField(row, errorList);        }        // 执行数据持久化        persistentBeanDataToDb(dataList, rowAction);    }       /**     * 导出csv文件(表头和行都以实体的方式)     *     * @param response     * @param head     * @param rowDataList     */    public static <T> void exportCsvWithBean(HttpServletResponse response, String fileName, T head, List<T> rowDataList) {        CsvWriter writer = null;        try {            // 设置响应头格式            response.setContentType(ExportConstant.EXCEL_CONTENT_TYPE);            response.setCharacterEncoding(ExportConstant.UTF_8);            response.setHeader(ExportConstant.CONTENT_DISPOSITION, ExportConstant.ATTACHMENT_FILENAME + fileName + ExportConstant.CSV_SUFFIX);            // 设置导出格式            CsvWriterSettings setting = getDefaultWriteSetting();            // 创见bean处理器,用于处理写入数据            BeanWriterProcessor<?> beanWriter = new BeanWriterProcessor<>(head.getClass());            setting.setRowWriterProcessor(beanWriter);            // 导出数据            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();            }        }    } 

  「使用案例如下:」

/**     * 导出案例     *     * @param response     */    public void exportUserListWithCsv(HttpServletResponse response) {        List<UserExportCsvVo> exportItem = new ArrayList<>();        // 查询数据        List<User> dbData = userService.list();        // 使用字符串数组方式作为表头导出csv数据        List<Object> head = Stream.of("id", "name", "password").collect(Collectors.toList());        List<List<Object>> dataList = new ArrayList<>();        for (User user : dbData) {            List<Object> row = new ArrayList<>();            row.add(user.getId());            row.add(user.getName());            row.add(user.getPassword());            dataList.add(row);        }        CsvExportUtil.exportCsvWithString(response, "demo", head, dataList);    } /**     * 导入用户数据案例(csv模式)     *     * @param file     */@Transactional(rollbackFor = Exception.class)    public void uploadUserListWithCsv(MultipartFile file) throws Exception {        // 此处先校验导入的文件类型是否为csv        String type = FileTypeUtil.getType(file.getInputStream());        if (StrUtil.isBlank(type) || type.contains(ImportConstant.CSV_TYPE)) {            // 返回校验失败信息            return;        }        User user = new User();        user.setId(100);        user.setName("外层");        user.setPassword("外层");        userService.save(user);        List<String> errorLogList = new ArrayList<>();        // 调用统一导入方法        // 方式一:使用csv数据映射到dto实体的方式进行数据导入        //CsvImportUtil.importCsvWithBean(file.getInputStream(), errorLogList, UserCsvDto.class, UserServiceImpl::saveUserListWithCsv);        // 方式二、使用csv数据映射到字符串数组的方式进行数据导入        CsvImportUtil.importCsvWithString(file.getInputStream(), errorLogList, UserCsvDto.class, UserServiceImpl::saveUserListWithCsvStringArrDemo);        // 如果存在解析异常,输出解析异常并进行事务回滚        if (CollUtil.isNotEmpty(errorLogList)) {            throw new RuntimeException(StrUtil.toString(errorLogList));        }    }

三、ftp工具

  Ftp文件上传下载相比excel、csv等出现的场景较少,「但是,如果你参与的项目是政府或者涉及到第三方旧系统对接的时候,很多时候就需要使用到它。因为很多旧系统或者政府项目使用的技术比较旧或者有制度限制,一般都是以文件的形式与你进行交互,此时ftp工具就很有效了。」

  Ftp工具使用的commons.NET开源框架进行实现,具体的集成流程之前单独使用一篇文章进行了非常详细的介绍,有需要的读者可以点击后面链接查看:手把手教你搭建ftp服务器,并用程序完成ftp上传下载功能

  「部分源码如下:」

/**     * 上传     *     * @return     */    public boolean upload(FtpUploadParam param) {        boolean flag = false;        FTPClient ftpClient = new FTPClient();        //1 测试连接        if (connect(ftpClient, param.getHostname(), param.getPort(), param.getUsername(), param.getPassword())) {            try {                //2 检查工作目录是否存在,不存在则创建                if (!ftpClient.changeWorkingDirectory(param.getWorkingPath())) {                    ftpClient.makeDirectory(param.getWorkingPath());                }                // 将文件编码成Ftp服务器支持的编码类型(FTP协议里面,规定文件名编码为iso-8859-1,所以目录名或文件名需要转码。)                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 测试连接        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;                // }                /*                 * 打开FTP服务器的PASS模式(不记得FTP协议支持的模式请翻到文章第一阶段)                 * 这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据. 因为ftp                 * server可能每次开启不同的端口来传输数据,但是在linux上,由于安全限制,可能某些端口没有开启,可能出现出现阻塞                 */                ftpClient.enterLocalPassiveMode();                // 设置文件的传输方式-二进制                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);                // 将文件编码成Ftp服务器支持的编码类型(FTP协议里面,规定文件名编码为iso-8859-1,所以目录名或文件名需要转码。)                // 缺少编码转换会导致:从FTP服务器下载下来的文件是破损的,无法被打开                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 错误:{}", 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 错误:{}", e);        }    }

三、分布式文件系统工具

  「非结构化数据通常是使用文件的方式进行存储,这时候不可避免地要使用到文件系统进行管理。」 分布式文件系统工具使用了第三方开源框架seaweedfs进行搭建,可以实现程序上传,删除、下载、查询,并有文件分布式存储,避免单点故障,节约成本等特点。

  前面也专门通过一篇文章讲解了:为何要使用seaweedfs框架搭建分布式文件系统的,感兴趣的读者可以通过下方链接进行查看:Gitee图床崩溃后,我使用Seaweedfs搭建了文件系统并封装成轮子开源

  「部分源码如下:」

/**     * @description: 上传单个文件到文件服务器     * @param: file     * @return: 文件的fid + 文件的请全访问地址     * @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);        // 获取上传文件的访问地址        String fileUrl = fileTemplate.getFileUrl(handleStatus.getFileId());        // 关闭当前连接        fileSource.shutdown();        return handleStatus.getFileId() + StrUtil.DASHED + fileUrl;    }/**     * @description: 根据文件下载文件     * @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);        // 设置响应头        response.setContentType(CommonConstant.CONTENT_TYPE);        response.setCharacterEncoding(CommonConstant.UTF_8);        String encodeFileName = buildingFileNameAdapterBrowser(request, fileName);        response.setHeader(CommonConstant.CONTENT_DISPOSITION, CommonConstant.ATTACHMENT_FILENAME + encodeFileName);        // 读取并写入到响应输出        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);        }    }

工具更新

  到此为止,轮子之王已集成的工具就介绍完毕了,后续还会不断更新、集成新的轮子,下面给大家介绍一下下一段时间项目的一些工作(「如果读者有想要集成的轮子,欢迎提issue或者这文章下面留言」):

  • 集成一个可视化界面,更好地介绍开源工具中各个轮子的引入案例,方便大家使用。
  • 集成word文件导出工具
  • 集成pdf文件导出工具
  • 集成复杂报表的报表导出工具(使用freemaker框架)
  • 待更新...

集成方案介绍关联文章

  • 手把手教你搭建ftp服务器,并用程序完成ftp上传下载功能
  • 集成csv工具的前因后果
  • Gitee图床崩溃后,我使用Seaweedfs搭建了文件系统并封装成轮子开源

写在最后

  开源之路不容易,开源之心不忘记!「如果博主开源的项目对您有所帮助,请给项目star,给博主更多动力,如果阅读文章给您有所帮助,请给博主点赞、关注。」

  该开源项目会持续更新和维护,希望有更多读者能够提出建议和想法,



Tags:开源工具   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
开源工具Ventoy更新:新增对FreeBSD 14.0的支持
近日,开源装机工具Ventoy发布了1.0.97版本的更新。本次更新的主要亮点是新增了对FreeBSD 14.0版本的支持,并修复了启动问题以及解决了几个Linux独有的bug等。同时,官方还修复了...【详细内容】
2024-01-25  Search: 开源工具  点击:(42)  评论:(0)  加入收藏
Java优秀开源工具库:Hutool和Jodd有什么区别?
Hutool 和 Jodd 都是 Java 生态中的优秀工具库和框架,它们都为 Java 开发者提供了一系列便捷的功能,但它们的侧重点、设计哲学和提供的组件有所不同。Hutool:主要是一个工具类...【详细内容】
2023-10-31  Search: 开源工具  点击:(62)  评论:(0)  加入收藏
8个用于数据挖掘的优秀开源工具
在机器学习的流程中数据挖掘是重要的一环。数据挖掘是从大量数据中提取隐藏的或未知,但可能有用信息的过程。这些数据最终会被加上标签,用于模型的训练。很多的数据科学家和机...【详细内容】
2023-07-22  Search: 开源工具  点击:(178)  评论:(0)  加入收藏
盘点5个非常实用的开源工具
大家好,我是Echa.最近有部分粉丝私信我,有么有提高运营方面工作效率实用的开源工具,找啊找,今天给老铁们分享5个非常实用的开源工具。创作不易,喜欢的老铁们加个关注,点个赞,后面会...【详细内容】
2022-12-01  Search: 开源工具  点击:(382)  评论:(0)  加入收藏
有了这个开源工具后,我五点就下班了
前言&emsp;&emsp;「一个优秀的开发者,一定是会利用各种工具来提升自己的开发效率。」 前段时间,博主在Gitee/Github开源了一个提升开发效率的工具,工具内集成了各种常用工具如c...【详细内容】
2022-08-09  Search: 开源工具  点击:(419)  评论:(0)  加入收藏
元宇宙7个开源工具和框架让开发不用从零开始
随着人们对元宇宙(metaverse)兴趣的增长,帮助开发metaverse的工具和平台的数量也在增加。以下是metaverse开发人员的优秀资源。如果你想为metaverse构建应用程序或服务,你不必从...【详细内容】
2022-07-13  Search: 开源工具  点击:(614)  评论:(0)  加入收藏
4个用于在云原生环境中运行虚拟机的开源工具
遗留工作负载是否阻止你走向云原生?这里有四种解决方案,可以在云原生环境中运行虚拟机。许多IT专业人士想走向原生云。但是,你有传统的工作负载,比如单体,它只能在虚拟机上运行。...【详细内容】
2022-07-05  Search: 开源工具  点击:(346)  评论:(0)  加入收藏
eHIDS 一款基于eBPF的HIDS开源工具
一 前言IDS一般指入侵检测系统。 入侵检测系统(intrusion detection system,简称“IDS”)是一种对网络传输进行即时监视,在发现可疑传输时发出警报或者采取主动反应措施的网络安...【详细内容】
2022-04-18  Search: 开源工具  点击:(353)  评论:(0)  加入收藏
2022 年保护 Linux 服务器的 10 种流行开源工具
概述 我们知道linux与windows相比,LINUX提供了良好的安全性,它提供了各种安全措施来减轻并阻止黑客破坏你的系统。当然这是在你合理设置了linux安全策略的情况下。除了LINUX本...【详细内容】
2022-03-18  Search: 开源工具  点击:(312)  评论:(0)  加入收藏
5秒内克隆你的声音,并生成任何内容,这个开源工具细思极恐
开源前线(ID:OpenSourceTop) 猿妹整编综合自:https://github.com/babysor/MockingBird 大家应该都知道声音克隆技术,通俗的来说就是借助深度学习算法,可以完全模拟某个人的声音,而...【详细内容】
2021-09-01  Search: 开源工具  点击:(548)  评论:(0)  加入收藏
▌简易百科推荐
GitHub顶流"Web OS"——运行于浏览器的桌面操作系统、用户超100万、原生jQuery和JS编写
Puter 是近日在 GitHub 上最受欢迎的一款开源项目,正式开源还没到一周 &mdash;&mdash;star 数就已接近 7k。作者表示这个项目已开发 3 年,并获得了超过 100 万用户。根据介绍,P...【详细内容】
2024-03-10  OSC开源社区    Tags:GitHub   点击:(32)  评论:(0)  加入收藏
一文读懂 AutoGPT 开源 AI Agents
Hello folks,我是 Luga,今天我们继续来聊一下人工智能(AI)生态领域相关的技术 - AutoGPT AI Agents ,本文将聚焦在针对不同类型的 AutoGPT 技术进行解析,使得大家能够了解不同 A...【详细内容】
2023-11-27  架构驿站  微信公众号  Tags:AI Agents   点击:(259)  评论:(0)  加入收藏
了解一下开源许可协议
开源许可协议开源许可协议是指允许软件源代码公开、免费获取、使用、修改和分发的许可协议。开源许可协议的目的是促进软件的自由共享和协作,使得开发者可以共同改进和创造新...【详细内容】
2023-11-18  沐雨花飞蝶  微信公众号  Tags:开源   点击:(217)  评论:(0)  加入收藏
七个很实用的开源项目,我们一起学学吧!
本周特推的两个项目都是异常实用的项目,一个接棒上周的视频重制项目 video-retalking 这次则是直接将视频替换成另外一个语种;另外一个则是解决日志阅读问题的 tailspin,让你在...【详细内容】
2023-11-06  HelloGitHub  微信公众号  Tags:开源   点击:(388)  评论:(0)  加入收藏
八个适合程序员接私活赚钱的开源项目
智慧团购一套基于Spring Cloud和Vue.js的社区团购配送系统,经过真实的用户检验且完善的社区团购配送系统,社区团购配送系统包含管理台、集团总店(商家PC端)、城市合伙人、区域...【详细内容】
2023-10-13  前端充电宝  微信公众号  Tags:开源项目   点击:(276)  评论:(0)  加入收藏
八个优秀开源DevOps工具
DevOps(Development和Operations)是一组软件工程过程最佳实践,并非工具,旨在将制造世界的精益概念应用于软件世界。维基百科给出的定义是:“DevOps是一种重视软件开发人员(Dev)和IT...【详细内容】
2023-10-10  andflow  微信公众号  Tags:DevOps   点击:(291)  评论:(0)  加入收藏
开源存在风险的根本原因
漏洞仍然是可以预防的几乎所有(96%)的漏洞仍然是可以避免的。2023年本可以避免21亿次具有已知漏洞的OSS下载,因为有了更好的修复版本&mdash;&mdash;与2022年的百分比完全相同...【详细内容】
2023-10-09     企业网D1Net  Tags:开源   点击:(301)  评论:(0)  加入收藏
中国14岁初中生,开源Windows 12网页版,star数近2k
出品 | OSC开源社区(ID:oschina2013)前几天在网上冲浪,发现名为「Windows 12 网页版」的开源项目&mdash;&mdash;在网页端实现了Windows 12 的交互和 UI。项目亮点: 精美的 UI 设...【详细内容】
2023-09-07    OSC开源社区  Tags:开源   点击:(251)  评论:(0)  加入收藏
苹果开源FastViT:快速卷积Transformer的混合视觉架构
苹果此前在论文《FastViT: A Fast Hybrid Vision Transformer using Structural Reparameterization》中提出的 FastViT 架构已正式开源。论文地址:https://arxiv.org/pdf/23...【详细内容】
2023-08-16  OSC开源社区    Tags:FastViT   点击:(325)  评论:(0)  加入收藏
金融机构使用开源软件,有哪些潜在风险?
面对新技术,无法逃避,只有先行和后行,没有不执行。本文来自社区文章《论述金融机构使用开源软件的潜在风险》及对该文的评论交流,由社区同行分享,也欢迎大家参与探讨。@朱向东 中...【详细内容】
2023-08-14    IT168企业级  Tags:开源软件   点击:(284)  评论:(0)  加入收藏
站内最新
站内热门
站内头条