go语言生成文档的示例代码

go语言生成文档的示例代码

export GOPROXY=https://mirrors.aliyun.com/goproxy/
go get github.com/xuri/excelize/v2  # 读取 Excel
go get github.com/unidoc/unioffice/document  # 处理 Word
package main

import (
    "fmt"
    "log"
    "os"
    "path/filepath"
    "strings"
    "sync"

    "github.com/xuri/excelize/v2" // 读取 Excel
    "github.com/unidoc/unioffice/document" // 处理 Word
)

func main() {
    // 1. 读取 Excel 数据
    excelPath := "data.xlsx"
    rows, err := readExcel(excelPath)
    if err != nil {
        log.Fatalf("读取 Excel 失败: %v", err)
    }

    // 2. 加载 Word 模板
    templatePath := "template.docx"
    docTemplate, err := document.Open(templatePath)
    if err != nil {
        log.Fatalf("打开模板失败: %v", err)
    }

    // 3. 创建输出目录
    outputDir := "output_docs"
    if err := os.MkdirAll(outputDir, 0755); err != nil {
        log.Fatalf("创建输出目录失败: %v", err)
    }

    // 4. 并发生成 Word 文档(Go 的 Goroutine 实现高并发)
    var wg sync.WaitGroup
    sem := make(chan struct{}, 10) // 控制并发数(最多 10 个 Goroutine)

    for _, row := range rows {
        wg.Add(1)
        sem <- struct{}{} // 占用信号量,限制并发数

        go func(id, content string) {
            defer wg.Done()
            defer func() { <-sem }() // 释放信号量

            // 替换模板中的占位符
            doc := docTemplate.Copy() // 复制模板(避免修改原模板)
            replacePlaceholders(doc, id, content)

            // 保存 Word 文件
            filename := filepath.Join(outputDir, fmt.Sprintf("%s.docx", id))
            if err := doc.Save(filename); err != nil {
                log.Printf("保存 %s 失败: %v", filename, err)
                return
            }
            log.Printf("生成成功: %s", filename)
        }(row["ID"], row["Content"])
    }

    wg.Wait()
    fmt.Println("所有文档生成完成!")
}

// readExcel 读取 Excel 数据,返回 map 列表(每行一个 map)
func readExcel(path string) ([]map[string]string, error) {
    f, err := excelize.OpenFile(path)
    if err != nil {
        return nil, err
    }
    defer f.Close()

    // 获取 Sheet1 的所有行
    rows, err := f.GetRows("Sheet1")
    if err != nil {
        return nil, err
    }

    // 转换为 map 列表(键是列名,值是单元格内容)
    var result []map[string]string
    headers := rows[0] // 第一行是表头
    for i := 1; i < len(rows); i++ {
        row := rows[i]
        data := make(map[string]string)
        for j, header := range headers {
            if j < len(row) {
                data[header] = row[j]
            }
        }
        result = append(result, data)
    }

    return result, nil
}

// replacePlaceholders 替换 Word 模板中的占位符
func replacePlaceholders(doc *document.Document, id, content string) {
    // 遍历所有段落
    for _, para := range doc.Paragraphs() {
        // 遍历段落中的所有文本块(Run)
        for _, run := range para.Runs() {
            text := run.Text()
            switch {
            case strings.Contains(text, "{{ID}}"):
                run.SetText(strings.ReplaceAll(text, "{{ID}}", id))
            case strings.Contains(text, "{{Content}}"):
                run.SetText(strings.ReplaceAll(text, "{{Content}}", content))
            }
        }
    }
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注