1942 发表于 2023-6-13 09:06

go语言编写的批量下载图片工具,附源码

本帖最后由 1942 于 2023-6-13 09:12 编辑

给同事写的一个批量下账图片的小工具,go语音编写的 代码有点粗糙, 附上源码 和 编译好的 win版本 。
打包mac 或者 linux 版本可以把 win32api 的调用去掉。
按照说明格式整理好excel文件即可。
=====================================================================
https://wwxq.lanzoub.com/b02kn2ayh
密码:hst9
听说发远程帖子能赚币子 {:1_918:}

=================================================================================





/*
Description: 下载excel中的图片
author: Phoenix
date: 20230613
email: 1044714221@qq.com
*/
package main

import (
      "errors"
      "fmt"
      "github.com/tealeg/xlsx"
      "io"
      "net/http"
      "os"
      "path/filepath"
      "strings"
      "sync"
      "syscall"
      "unsafe"
)

func main() {

      // 1. 获取当前文件位置
      dir, err := os.Getwd()
      if err != nil {
                Msg("Error", err.Error())
      }

      // 2. 获取当前文件夹下所有的excel文件
      fileList := make([]string, 0)
      filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { // 遍历当前文件夹下所有文件
                if filepath.Ext(path) == ".xlsx" {                                    // 判断文件后缀是否为.xlsx
                        fileList = append(fileList, path) // 将文件路径添加到fileList中
                }
                return nil
      })

      // 3. 读取excel文件
      for _, file := range fileList {
                // 获取文件名称
                fileName := filepath.Base(file)
                // 创建同名文件夹
                dirName := fileName[:len(fileName)-len(filepath.Ext(fileName))]
                os.Mkdir(dirName, os.ModePerm)
                dataList := ReadExcel(file)

                wg := sync.WaitGroup{}
                maxGoroutine := make(chan struct{}, 20) // 最大并发数

                for _, data := range dataList {
                        m := make(mapstring)
                        for k, v := range data {
                              m = v
                        }
                        wg.Add(1)
                        go func(m mapstring) {
                              maxGoroutine <- struct{}{}
                              DownLoadImgs(m["list"], m["name"], dir+"/"+dirName)
                              <-maxGoroutine
                              wg.Done()
                        }(m)
                }
                wg.Wait()
      }
      Msg("Success", "下载完成")
}

// ------------------------------ util ------------------------------

func DownLoadImgs(imgs string, filename, imgPath string) {
      fmt.Println("imgPath:", imgPath)
      // imgs 转为 []string按照逗号分隔
      urls := strings.Split(imgs, ",")
      for index, url := range urls {
                // 下载图片
                imgName := filepath.Base(url)
                imgTag := filepath.Ext(imgName) // 获取图片后缀
                imgPath2 := filepath.Join(imgPath, filename)
                os.Mkdir(imgPath2, os.ModePerm)
                imgName2 := filepath.Join(imgPath, filename, filename+"_"+fmt.Sprintf("%d", index+1)+imgTag)
                // 2. 下载图片
                DownloadFile(url, imgName2)
      }
}

// DownloadFile 下载图片
func DownloadFile(url, filename string) (err error) {
      resp, err := http.Get(url)
      if err != nil {
                Msg("Error1", err.Error())
                os.Exit(1)
                return errors.New("下载图片失败" + err.Error())
      }
      defer resp.Body.Close()
      file, err := os.Create(filename)
      if err != nil {
                Msg("Error2", err.Error())
                os.Exit(1)
                return errors.New("创建图片失败" + err.Error())
      }
      defer file.Close()
      _, err = io.Copy(file, resp.Body)
      if err != nil {
                Msg("Error3", err.Error())
                os.Exit(1)
                return errors.New("保存图片失败" + err.Error())
      }
      return nil
}

// Msg 弹窗
func Msg(msgType string, msg string) {
      user32 := syscall.MustLoadDLL("user32.dll")
      MessageBoxW := user32.MustFindProc("MessageBoxW")

      title := msgType
      text := msg
      ret, _, _ := MessageBoxW.Call(
                0,
                uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))),
                uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))),
                0)
      if ret == 0 {
                return
      }
}

// ReadExcel 读取xlsx文件
func ReadExcel(filename string) []mapstring {
      var data []mapstring
      xlFile, err := xlsx.OpenFile(filename)
      if err != nil {
                fmt.Println(err)
                return data
      }
      for _, sheet := range xlFile.Sheets {
                headers := make([]string, len(sheet.Rows.Cells))
                for i, cell := range sheet.Rows.Cells {
                        headers = cell.String()
                }
                for _, row := range sheet.Rows {
                        rowData := make(mapstring)
                        for i, cell := range row.Cells {
                              if headers == "" {
                                        continue
                              }
                              rowData] = cell.Value
                        }
                        data = append(data, rowData)
                }
      }
      return data
}

xavier001 发表于 2023-6-13 09:21

写得不错,提个建议,下载之前判断一下文件是否存在,如果存在的话,就跳过不下载,这样可能体验会好一些,不用每次点开都重新下载全部

onlyclxy 发表于 2023-6-13 13:43

看见go过来试了试..为啥一直循环下载一个个图....
这个东西倒是用不上.就是一半的程序   不过源码感谢提供参考

ynboyinkm 发表于 2023-6-13 09:13

正在纠结要不要学习GO

wintop 发表于 2023-6-13 09:30

ynboyinkm 发表于 2023-6-13 09:13
正在纠结要不要学习GO

边学边玩。我也是学了个皮毛,现在都忘记了,工作需求又搞起来了py{:301_972:}

zhiaipojie0313 发表于 2023-6-13 09:38

支持支持

1942 发表于 2023-6-13 09:50

xavier001 发表于 2023-6-13 09:21
写得不错,提个建议,下载之前判断一下文件是否存在,如果存在的话,就跳过不下载,这样可能体验会好一些, ...

有时候同名文件存在, 但是文件内容变了, 还不如覆写

lockxxx 发表于 2023-6-13 09:57

支持原创

可坏 发表于 2023-6-13 10:03

没懂,下载图片存储到xls里面?

Caitingting 发表于 2023-6-13 10:43

看完说明书,一种邪恶的用法在我的心中萌芽了{:1_918:}{:1_918:}{:1_918:}{:1_918:}

qiqi2050352 发表于 2023-6-13 10:44

不错,谢谢分享
页: [1] 2
查看完整版本: go语言编写的批量下载图片工具,附源码