写点什么

ARTS 打卡 第三周,向阳而生

作者:海风极客
  • 2023-09-10
    北京
  • 本文字数:3309 字

    阅读完需:约 11 分钟

第三周来咯~

Algorithm

选自力扣网站上的题:移除元素

func removeElement(nums []int, val int) int {    left, right := 0, len(nums)    for left < right {        if nums[left] == val {            nums[left] = nums[right-1]            right--        } else {            left++        }    }    return left}
复制代码

Review

地址:https://www.javacodegeeks.com/2023/08/foundations-of-effective-software-engineering-mastering-the-seven-core-principles.html


Modularity refers to the practice of dividing a software system into smaller,independent, and cohesive components or modules.


模块化是指将软件系统划分为更小、独立和有凝聚力的组件或模块的做法。


Each module serves a specific function and can be developed, tested, and maintained independently, which simplifies the overall complexity of the system.


每个模块都有特定的功能,可以独立开发、测试和维护,这简化了系统的整体复杂性。


When modules are properly designed, they can be easily interchanged or reused in different projects, leading to more efficient development and reducing the chance of introducing errors.


当模块设计得当时,它们可以在不同的项目中轻松地交换或重用,从而提高开发效率并减少引入错误的机会。


Abstraction, on the other hand, involves hiding the implementation details of a module and exposing only the essential features and interfaces that other modules need to interact with it. This allows developers to focus on what a module does rather than how it does it, promoting clarity and reducing code dependencies.


另一方面,抽象涉及隐藏模块的实现细节,只暴露其他模块与之交互所需的基本功能和接口。这使开发人员能够专注于模块的功能,而不是它是如何做到的,从而提高清晰度并减少代码依赖性。

Technique/Tips

本次分享的小技巧:Go 读取文件


GitHub 链接:https://github.com/qax-os/excelize


Excelize 是一个用纯 Go 语言编写的库,提供了一组函数,可以对 XLAM / XLSM / XLSX / XLTM / XLTX 文件进行读写。支持读写由 Microsoft Excel™2007 及以后版本生成的电子表格文档。通过高兼容性支持复杂组件,并提供流 API 从具有大量数据的工作表中生成或读取数据。该库需要 Go 1.16 或更高版本


那么本篇文章将会介绍我们操作 Excel 的常用功能,如下:


  • 生成一个新的 Excel 文件

  • 向 Excel 文件中追加内容

  • 解析 Excel 文件内容

  • 使用 Http 协议上传并解析 Excel 文件

  • 使用 Http 协议将数据转换为 Excel 文件并下载

1 下载依赖库

go get github.com/xuri/excelize
# Go Modules使用这个命令go get github.com/xuri/excelize/v2
复制代码

2 具体操作

2.1 生成一个新的 Excel 文件

func WriteNewExcel() {   f := excelize.NewFile()   // 创建一个sheet   index := f.NewSheet("Sheet2")   // 根据sheet和坐标 确定一个值   // 例如f.SetCellValue("Sheet2", "A2", "Hello world.")就是在Sheet表中A列第2行的格子里填入Hello world.   f.SetCellValue("Sheet2", "A2", "Hello world.")   f.SetCellValue("Sheet1", "B1", 100)   f.SetCellValue("Sheet1", "B2", 100)   // 将新的sheet添加到Excel中   f.SetActiveSheet(index)   // 保存Excel   if err := f.SaveAs("Book1.xlsx"); err != nil {      fmt.Println(err)   }}
复制代码

2.2 向 Excel 文件中追加内容

func WriteExcel() {   f, _ := excelize.OpenFile("Book1.xlsx")   index := f.NewSheet("Sheet2")   f.SetCellValue("Sheet2", "A2", "Hello world.")   f.SetCellValue("Sheet1", "B1", 100)   f.SetCellValue("Sheet1", "B2", 100)   f.SetActiveSheet(index)   if err := f.SaveAs("Book1.xlsx"); err != nil {      fmt.Println(err)   }}
复制代码

2.3 解析 Excel 文件内容

func ReadExcel() {   f, err := excelize.OpenFile("Book1.xlsx")   if err != nil {      fmt.Println(err)      return   }   defer func() {      if err := f.Close(); err != nil {         fmt.Println(err)      }   }()   // 根据sheet和坐标读取某一个格子的值   cell, err := f.GetCellValue("Sheet1", "B2")   if err != nil {      fmt.Println(err)      return   }   fmt.Println(cell)   // 按行读取全部   rows, err := f.GetRows("Sheet1")   if err != nil {      fmt.Println(err)      return   }   for _, row := range rows {      for _, colCell := range row {         fmt.Print(colCell, "\t")      }      fmt.Println()   }}
复制代码

2.4 使用 Http 协议上传并解析 Excel 文件

func HttpReadExcel() {   f := func(read io.Reader) {      file, err := excelize.OpenReader(read)      if err != nil {         fmt.Println(err)         return      }      for _, item := range file.GetSheetList() {         rows, _ := file.GetRows(item)         // rows是一个二维数组         for i := range rows {            strs := rows[i]            for j := range strs {               str := rows[i][j]               fmt.Println(str)            }         }      }   }   http.HandleFunc("/excel", func(w http.ResponseWriter, r *http.Request) {      file, _, err := r.FormFile("file")      if err != nil {         fmt.Println(err)         return      }      fileBytes, err := ioutil.ReadAll(file)      if err != nil {         fmt.Println(err)         return      }      reader := bytes.NewReader(fileBytes)      f(reader)      w.Write([]byte("Hello Http Get!"))   })   http.ListenAndServe(":8080", nil)}
复制代码

2.5 使用 Http 协议将数据转换为 Excel 文件并下载

func HttpDownloadExcel() {   fun := func(fileName string) *bytes.Reader {      f := excelize.NewFile()      f.SetCellValue("Sheet1", "B1", 100)      err := f.SaveAs(fileName)      if err != nil {         fmt.Println(err)      }      var buffer bytes.Buffer      _ = f.Write(&buffer)      return bytes.NewReader(buffer.Bytes())   }   http.HandleFunc("/downloadExcel", func(w http.ResponseWriter, r *http.Request) {      reader := fun("Book2.xlsx")      // 重新设置文件名称      w.Header().Set("Content-Disposition", "attachment; filename="+"Book2.xlsx")      io.Copy(w, reader)   })   http.ListenAndServe(":8080", nil)}
复制代码

3 小总结

以上功能只需灵活扩展后基本上就可以覆盖大部分业务了,但是有一点需要注意,在 2.5 使用 Http 协议将数据转换为 Excel 文件并下载这个操作中,需要将文件进行重命名,这个名称可以自定义,也可以由服务端指定,但是需要以相关文件类型的名称做后缀,否则会输出 zip 压缩文件,很难看懂。

Share

什么是面向接口编程?为什么要面向接口编程?

简单的讲,面向接口编程是一种编程规范,一种设计规范,可以更好的进行需求的定义和业务的扩展,我们可以从以下三个方面来探讨为什么要面向接口编程:

开闭原则:对扩展开放,对修改关闭,接口正是如此,定义接口后不再修改,只扩展其对应的实现。

依赖倒置原则:高层模块不应该依赖于低层模块,他们应该共同依赖于抽象,而这个抽象就是接口。

增加抽象层、解耦:接口显然是对抽象的一个封装,能够达到解耦的目的。

到这里,讲了这么多,其实最终的总结很简单:接口的本质就是抽象和规范,接口是抽象的产物,应用于规范。

使用接口可以更好的将我们的系统进行解耦,不管是多系统之间(如 RPC 框架),还是同一系统多模块之间,接口所扮演的抽象的角色都是不可替代的。

今天的分享就到这里,如有哪里理解的不够深入,请读者朋友不吝赐教哈~

小结

本次的分享就到这里喽,总体来说每天花一些时间来分别研究这几件事情,然后一周的周末来一个总结,这样的方式也是相当不错的。

发布于: 刚刚阅读数: 4
用户头像

海风极客

关注

做兴趣使然的Hero 2021-01-14 加入

Just do it.

评论

发布
暂无评论
ARTS 打卡 第三周,向阳而生_ARTS 打卡计划_海风极客_InfoQ写作社区