package exporter import ( "archive/zip" "compress/flate" "fmt" "io" "os" "path/filepath" "strings" "time" ) // ZipFiles 将分片文件打包为压缩zip并返回路径与大小,同时清理源xlsx分片文件 func ZipFiles(jobID uint64, files []string) (string, int64) { baseDir := "storage/export" _ = os.MkdirAll(baseDir, 0755) zipPath := filepath.Join(baseDir, fmt.Sprintf("job_%d_%d.zip", jobID, time.Now().Unix())) zf, err := os.Create(zipPath) if err != nil { return zipPath, 0 } defer zf.Close() zw := zip.NewWriter(zf) // 注册 DEFLATE 压缩器 zw.RegisterCompressor(zip.Deflate, func(out io.Writer) (io.WriteCloser, error) { w, err := flate.NewWriter(out, flate.DefaultCompression) if err != nil { return nil, err } return w, nil }) for _, p := range files { f, err := os.Open(p) if err != nil { continue } // 创建压缩文件头,指定使用 DEFLATE 压缩 w, err := zw.CreateHeader(&zip.FileHeader{ Name: filepath.Base(p), Method: zip.Deflate, // 使用 DEFLATE 压缩 }) if err != nil { f.Close() continue } _, _ = io.Copy(w, f) f.Close() } _ = zw.Close() st, err := os.Stat(zipPath) if err != nil { return zipPath, 0 } // 清理xlsx分片文件以节省空间 for _, fp := range files { if strings.HasSuffix(strings.ToLower(fp), ".xlsx") { _ = os.Remove(fp) } } return zipPath, st.Size() }