使用Golang拉取阿里云费用账单到Excel
初始化go项目
- 初始化项目,如果是简单的脚本,怎么方便怎么来
- 直接进入项目目录初始化也行
cd /apps/app/QueryBillExcel/
go mod init QueryBillExcel
go mod init gitee.com/xxx/skills/
go env -w GOPROXY=https://goproxy.cn,direct
阿里云文档
- 使用的阿里云的
QueryBillOverview
- 具体使用到什么参数我都写到脚本的结构体中了,有一些我没用我就注释了
https://help.aliyun.com/document_detail/472986.html?spm=a2c4g.2399685.0.0.67cd9aa2WpgYAV
https://api.aliyun.com/api/BssOpenApi/2017-12-14/QueryBillOverview?spm=a2c4g.472986.0.0.6441a859jhnwCv&RegionId=cn-shenzhen
脚本
- 具体不解释了,里面有注释
- 具体情况可以将
Print大法
注释去掉,排错
package main
import (
// "encoding/json"
"errors"
"fmt"
"os"
// "strings"
bssopenapi20171214 "github.com/alibabacloud-go/bssopenapi-20171214/v5/client"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
util "github.com/alibabacloud-go/tea-utils/v2/service"
"github.com/alibabacloud-go/tea/tea"
"github.com/xuri/excelize/v2"
)
// 定义QueryBillOverview账单结构体来映射响应中的Item
type BillItem struct {
ProductName string `json:"ProductName"` // 产品名称
ProductDetail string `json:"ProductDetail"` // 产品明细
ProductCode string `json:"ProductCode"` // 产品代码
DeductedByCashCoupons float64 `json:"DeductedByCashCoupons"` // 代金卷抵扣
InvoiceDiscount float64 `json:"InvoiceDiscount"` // 优惠金额
PretaxGrossAmount float64 `json:"PretaxGrossAmount"` // 原始金额
PretaxAmount float64 `json:"PretaxAmount"` // 应付金额
// AdjustAmount float64 `json:"AdjustAmount"` // 信用额度退款抵扣
// BillAccountID string `json:"BillAccountID"` // 账单所属账号ID
// BillAccountName string `json:"BillAccountName"` // 账号所属账号名称
// BizType string `json:"BizType"` // 业务类型
// CashAmount float64 `json:"CashAmount"` // 现金支付
// CommodityCode string `json:"CommodityCode"` // 商品code, 与费用中心产品明细code一致
// Currency string `json:"Currency"`
// DeductedByCoupons float64 `json:"DeductedByCoupons"` // 优惠劵抵扣
// DeductedByPrepaidCard float64 `json:"DeductedByPrepaidCard"` // 储蓄卡抵扣
// Item string `json:"Item"`
// OutstandingAmount float64 `json:"OutstandingAmount"` // 为结清金额
// OwnerID string `json:"OwnerID"` // 账单OwnerID
// PaymentAmount float64 `json:"PaymentAmount"` // 现金支付
// PipCode string `json:"PipCode"` // 产品code,与费用中心账单产品一只
// ProductType string `json:"ProductType"` // 产品类型
// RoundDownDiscount string `json:"RoundDownDiscount"` // 抹零优惠
// SubscriptionType string `json:"SubscriptionType"`
}
func CreateClient() (*bssopenapi20171214.Client, error) {
config := &openapi.Config{
AccessKeyId: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")),
AccessKeySecret: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")),
}
config.Endpoint = tea.String("business.aliyuncs.com")
client, err := bssopenapi20171214.NewClient(config)
return client, err
}
func foo(month string) ([]BillItem, error) {
client, err := CreateClient()
if err != nil {
return nil, err
}
queryBillOverviewRequest := &bssopenapi20171214.QueryBillOverviewRequest{
BillingCycle: tea.String(month),
//SubscriptionType: tea.String("PayAsYouGo"),
//ProductCode: tea.String("cbs"),
//ProductType: tea.String("cbs_post"),
//BillOwnerId: tea.Int64(1186093715620322),
}
runtime := &util.RuntimeOptions{}
response, err := client.QueryBillOverviewWithOptions(queryBillOverviewRequest, runtime)
if err != nil {
var sdkErr *tea.SDKError
if errors.As(err, &sdkErr) {
fmt.Println(sdkErr.Message)
} else {
fmt.Println(err.Error())
}
return nil, err
}
// fmt.Println("Test1.Print大法.赋值前查看数据结构:", response.Body.Data.Items.Item)
// 定义items为[]BillItem,但没有赋值
var items []BillItem
for _, item := range response.Body.Data.Items.Item {
billItem := BillItem{
ProductName: *item.ProductName, // 产品名称
ProductDetail: *item.ProductDetail, // 产品明细
ProductCode: *item.ProductCode, // 产品代码
DeductedByCashCoupons: float64(*item.DeductedByCashCoupons), // 代金卷抵扣
InvoiceDiscount: float64(*item.InvoiceDiscount), // 优惠金额
PretaxGrossAmount: float64(*item.PretaxGrossAmount), // 原始金额
PretaxAmount: float64(*item.PretaxAmount), // 应付金额
}
items = append(items, billItem)
// fmt.Println("Test2.Print大法.赋值后查看数据结构:", items)
}
return items, nil
}
func main() {
f := excelize.NewFile()
// 创建一个新的Sheet
f := excelize.NewFile()
index, err := f.NewSheet(sheetNameStr)
if err != nil {
fmt.Println("Failed to create sheet:", sheetNameStr, err)
return
}
if index == 0 {
fmt.Println("Failed to create sheet:", sheetNameStr)
return
}
for i := 1; i <= 9; i++ {
var month string
if i < 10 {
month = fmt.Sprintf("2024-0%d", i)
} else {
month = fmt.Sprintf("2024-%d", i)
}
fmt.Println(month)
// 设置表头
headers := []string{"A", "B", "C", "D", "E", "F", "G", "H"} // 对应的列
headerData := []string{"id", "产品名称", "产品明细", "产品代码", "代金卷抵扣", "优惠金额", "原始金额", "应付金额"}
row := 1
for colIndex, header := range headerData {
cell := headers[colIndex] + fmt.Sprintf("%d", row)
f.SetCellValue(month, cell, header)
}
// 获取数据
items, err := foo(month)
if err != nil {
panic(err)
}
// fmt.Println("Test3.Print大法.fou循环前验证", items)
// for _, item := range items {
// fmt.Printf("产品名称: %s\n 产品明细: %s\n 产品代码: %s\n 代金卷抵扣: %.2f\n 优惠金额: %.2f\n 原始金额: %.2f\n 应付金额: %.2f\n", item.ProductName, item.ProductDetail, item.ProductCode, item.DeductedByCashCoupons, item.InvoiceDiscount, item.PretaxGrossAmount, item.PretaxAmount)
// }
// 插入数据
id := 1
rowIndex := 2
for _, item := range items {
f.SetCellValue(month, fmt.Sprintf("A%d", rowIndex), fmt.Sprintf("%d", id))
f.SetCellValue(month, fmt.Sprintf("B%d", rowIndex), item.ProductName)
f.SetCellValue(month, fmt.Sprintf("C%d", rowIndex), item.ProductDetail)
f.SetCellValue(month, fmt.Sprintf("D%d", rowIndex), item.ProductCode)
f.SetCellFloat(month, fmt.Sprintf("E%d", rowIndex), item.DeductedByCashCoupons, 2, 32)
f.SetCellFloat(month, fmt.Sprintf("F%d", rowIndex), item.InvoiceDiscount, 2, 32)
f.SetCellFloat(month, fmt.Sprintf("G%d", rowIndex), item.PretaxGrossAmount, 2, 32)
f.SetCellFloat(month, fmt.Sprintf("H%d", rowIndex), item.PretaxAmount, 2, 32)
id++
rowIndex++
}
// 保存文件
filename := fmt.Sprintf("2024年度费用账单.xlsx")
if err := f.SaveAs(filename); err != nil {
fmt.Println(err)
}
}
}
go mod tidy