Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Excelize generates a file with a size and empty content #1700

Closed
L4nn15ter opened this issue Oct 24, 2023 · 12 comments
Closed

Excelize generates a file with a size and empty content #1700

L4nn15ter opened this issue Oct 24, 2023 · 12 comments
Labels
needs more info This issue can't reproduce, need more info

Comments

@L4nn15ter
Copy link
Contributor

Description

Steps to reproduce the issue:
1.使用excelize在本地测试生成了一个WPS可读且有内容的文件;
2.将服务部署到linux(Red Hat)上,生成了一个具有大小的xlsx文件,但WPS打开显示空白;
3.使用其它工具(飞书在线表格)打开可以正常读取

Describe the results you received:
file
image

inside
image

Describe the results you expected:
image

Output of go version:
go 1.20.3

(paste your output here)

Excelize version or commit ID:
V2

(paste here)

Environment details (OS, Microsoft Excel™ version, physical, etc.):
Windows: Windows 10 pro
Linux: Linux version 3.10.0-1160.21 Red Hat 4.8.5-44
WPS: 15712

@xuri
Copy link
Member

xuri commented Oct 24, 2023

Thanks for your issue. Which version of the Excelize library are you using? Try to upgrade the master branch code, if it still doesn't work, please show us a complete, standalone example program or reproducible demo.

@xuri xuri added the needs more info This issue can't reproduce, need more info label Oct 24, 2023
@L4nn15ter
Copy link
Contributor Author

IMG_0976 IMG_0977 by excel

@xuri
Copy link
Member

xuri commented Oct 24, 2023

Thanks for your feedback. Did you tried upgrade the master branch code? It still doesn't work? Could you show us a complete, standalone example program or reproducible demo?

@xuri
Copy link
Member

xuri commented Oct 25, 2023

Did you tried upgrade the master branch code? If it still doesn't work, please show us a complete, standalone example program or reproducible demo. We don't know the value of the variable v, and the definition of the utils.Destruct function is missing, so we can't reproduce this via your code.

@xuri xuri changed the title Excelize generates a file with a size and empty content。 Excelize generates a file with a size and empty content Oct 25, 2023
@xuri xuri removed the needs more info This issue can't reproduce, need more info label Oct 25, 2023
@L4nn15ter
Copy link
Contributor Author

I'm sorry, due to my mistake, I mistakenly deployed the locally generated xlsx file to the server during CI/CD, and then used sz to download it locally as the generated file, so that I mistakenly thought that the problem was caused by http transmission, but just migrated the directory, used the code in my morning comment, used the sz command to download to the local, and found that it was a blank file with size, which temporarily ruled out the possibility of abnormal HTTP transmission, so please review the above code, See if the problem can be reproduced, the version is github.com/xuri/excelize/v2 v2.8.1-0.20231023160552-a8cbcfa39b7c, go version: 1.20

@L4nn15ter L4nn15ter reopened this Oct 25, 2023
@xuri
Copy link
Member

xuri commented Oct 25, 2023

Please follow the issue template, show us a COMPLETE, STANDALONE example program or reproducible demo after simplified. The definition of the *gin.Context, BlessingConf and pkg is missing, so we can't reproduce this via your code.

@xuri xuri added the needs more info This issue can't reproduce, need more info label Oct 25, 2023
@L4nn15ter
Copy link
Contributor Author

func TestExcel() (filePath string, err error) {
	xlsx := excelize.NewFile()
	var (
		fileName string
	)

	titles := []string{"权重", "中文标题", "中文内容", "英语标题", "英语内容"}

	sheetName := "配置表"

	// 设置表名
	if err = xlsx.SetSheetName("Sheet1", sheetName); err != nil {
		return
	}

	// 设置标题
	if err = xlsx.SetSheetRow(sheetName, "A1", &titles); err != nil {
		return
	}

	content := []BlessingConf{
		{
			Weight: 1,
			Content: Content{
				Zh: lang{
					Title:   "测试标题1",
					Content: "测试内容1",
				},
				En: lang{
					Title:   "Test Title 1",
					Content: "Test Content 1",
				},
			},
		},
		{
			Weight: 2,
			Content: Content{
				Zh: lang{
					Title:   "测试标题2",
					Content: "测试内容2",
				},
				En: lang{
					Title:   "Test Title 2",
					Content: "Test Content 2",
				},
			},
		},
		{
			Weight: 3,
			Content: Content{
				Zh: lang{
					Title:   "测试标题3",
					Content: "测试内容3",
				},
				En: lang{
					Title:   "Test Title 3",
					Content: "Test Content 3",
				},
			},
		},
	}
	for i, v := range content {
		rowSlice := []any{v.Weight, v.Content.Zh.Title, v.Content.Zh.Content, v.Content.En.Title, v.Content.En.Content}

		if err = xlsx.SetSheetRow(sheetName, fmt.Sprintf("A%d", i+2), &rowSlice); err != nil {
			return
		}
	}

	fileName = fmt.Sprintf("test_template_%d", time.Now().Unix())
	filePath = "./resource/tmp/" + fileName + ".xlsx"

	style, err := xlsx.NewStyle(&excelize.Style{Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"}})
	if err != nil {
		return
	}

	sheetList := xlsx.GetSheetList()
	for _, sheet := range sheetList {
		rows, err := xlsx.GetRows(sheet)
		if err != nil {
			return "", err
		}
		if err = xlsx.SetRowStyle(sheet, 1, len(rows), style); err != nil {
			return "", err
		}
	}
	if err = xlsx.SaveAs(filePath); err != nil {
		return "", err
	}

	return filePath, nil
}

@xuri
Copy link
Member

xuri commented Oct 25, 2023

Please follow the issue template, show us a complete, standalone example program or reproducible demo after simplified. The definition of BlessingConf and lang still missing in your code.

@L4nn15ter
Copy link
Contributor Author

Sorry, this is my first time mentioning issuse, thank you for your help

type BlessingConf struct {
	Weight  int64   `json:"weight"`
	Content Content `json:"content"`
}

type Content struct {
	Zh lang `json:"zh"`
	En lang `json:"en"`
}

type lang struct {
	Title   string `json:"title"`
	Content string `json:"content"`
}
func TestExcel() (filePath string, err error) {
	xlsx := excelize.NewFile()
	var (
		fileName string
	)

	titles := []string{"权重", "中文标题", "中文内容", "英语标题", "英语内容"}

	sheetName := "配置表"

	// 设置表名
	if err = xlsx.SetSheetName("Sheet1", sheetName); err != nil {
		return
	}

	// 设置标题
	if err = xlsx.SetSheetRow(sheetName, "A1", &titles); err != nil {
		return
	}

	content := []BlessingConf{
		{
			Weight: 1,
			Content: Content{
				Zh: lang{
					Title:   "测试标题1",
					Content: "测试内容1",
				},
				En: lang{
					Title:   "Test Title 1",
					Content: "Test Content 1",
				},
			},
		},
		{
			Weight: 2,
			Content: Content{
				Zh: lang{
					Title:   "测试标题2",
					Content: "测试内容2",
				},
				En: lang{
					Title:   "Test Title 2",
					Content: "Test Content 2",
				},
			},
		},
		{
			Weight: 3,
			Content: Content{
				Zh: lang{
					Title:   "测试标题3",
					Content: "测试内容3",
				},
				En: lang{
					Title:   "Test Title 3",
					Content: "Test Content 3",
				},
			},
		},
	}
	for i, v := range content {
		rowSlice := []any{v.Weight, v.Content.Zh.Title, v.Content.Zh.Content, v.Content.En.Title, v.Content.En.Content}

		if err = xlsx.SetSheetRow(sheetName, fmt.Sprintf("A%d", i+2), &rowSlice); err != nil {
			return
		}
	}

	fileName = fmt.Sprintf("test_template_%d", time.Now().Unix())
	filePath = "./resource/tmp/" + fileName + ".xlsx"

	style, err := xlsx.NewStyle(&excelize.Style{Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"}})
	if err != nil {
		return
	}

	sheetList := xlsx.GetSheetList()
	for _, sheet := range sheetList {
		rows, err := xlsx.GetRows(sheet)
		if err != nil {
			return "", err
		}
		if err = xlsx.SetRowStyle(sheet, 1, len(rows), style); err != nil {
			return "", err
		}
	}
	if err = xlsx.SaveAs(filePath); err != nil {
		return "", err
	}

	return filePath, nil
}

@xuri xuri closed this as completed Oct 26, 2023
@xuri xuri added duplicate This issue or pull request already exists and removed needs more info This issue can't reproduce, need more info duplicate This issue or pull request already exists labels Oct 26, 2023
@xuri
Copy link
Member

xuri commented Oct 26, 2023

I have tested the master branch code with your code, and it works well. There are two different problems in your screenshot. I don't know if you mean you generated an empty worksheet or if the workbook was corrupted. There's still not enough info on code and attachments to reproduce this issue, so I'll close this issue. If you have any questions, please let me know to reopen this anytime.

@xuri xuri added the needs more info This issue can't reproduce, need more info label Oct 26, 2023
@panter-dsd
Copy link

panter-dsd commented Nov 9, 2023

I have the same issue. It works well locally on my host machine but I get the empty file from kubernetes.

version: v2.8.0
golang: 1.21.0

Here is my code:

package report

import (
	"context"
	"fmt"

	"github.com/pkg/errors"
	"github.com/xuri/excelize/v2"
)

type ExcelReportCreator struct{}

func NewExcelReportCreator() *ExcelReportCreator {
	return &ExcelReportCreator{}
}

func (c *ExcelReportCreator) Create(ctx context.Context, report Report) ([]byte, error) {
	file, err := c.createExcelReport("Sheet1", report)
	if err != nil {
		return nil, errors.Wrap(err, "create report")
	}

	defer func() { _ = file.Close() }()

	reportDataBuffer, err := file.WriteToBuffer()
	if err != nil {
		return nil, errors.Wrap(err, "write report data to buffer")
	}

	return reportDataBuffer.Bytes(), nil
}

func (c *ExcelReportCreator) createExcelReport(sheetName string, report Report) (*excelize.File, error) {
	file := excelize.NewFile()

	file, err := c.addHeaderToExcelReport(sheetName, file)
	if err != nil {
		return nil, errors.Wrap(err, "add headers to excel report")
	}

	data := map[string]func(Item) interface{}{
		"A%d": func(item Item) interface{} { return item.Creative.ID.String() },
		"B%d": func(item Item) interface{} { return item.Creative.ID.String() },
		"C%d": func(item Item) interface{} { return item.Creative.Type },
		"D%d": func(item Item) interface{} { return item.Creative.DistributionFormat },
		"E%d": func(item Item) interface{} { return item.Creative.Description },
		"F%d": func(item Item) interface{} { return 0 },
		"G%d": func(item Item) interface{} { return 0 },
		"H%d": func(item Item) interface{} { return item.Creative.Token },
		"I%d": func(item Item) interface{} { return item.Creative.RegisteredAt.Format("2006-01-02") },
		"J%d": func(item Item) interface{} { return item.Creative.Contract.ID.String() },
		"K%d": func(item Item) interface{} { return item.Creative.Contract.ID.String() },
		"L%d": func(item Item) interface{} { return item.Creative.Contract.Number },
		"M%d": func(item Item) interface{} { return item.Creative.Contract.Date.Format("2006-01-02") },
		"N%d": func(item Item) interface{} { return item.Creative.Contract.Amount },
		"O%d": func(item Item) interface{} { return item.Creative.Contract.Type },
		"P%d": func(item Item) interface{} { return item.Creative.Organization.ID.String() },
		"Q%d": func(item Item) interface{} { return item.Creative.Organization.ID.String() },
		"R%d": func(item Item) interface{} { return item.Creative.Organization.Name },
		"S%d": func(item Item) interface{} { return item.Creative.Organization.INN },
		"T%d": func(_ Item) interface{} { return report.VI.ID.String() },
		"U%d": func(_ Item) interface{} { return report.VI.ID.String() },
		"V%d": func(_ Item) interface{} { return report.VI.Name },
		"W%d": func(_ Item) interface{} { return report.VI.INN },
		"X%d": func(item Item) interface{} { return item.Stat.Show },
		"Y%d": func(item Item) interface{} { return item.Stat.Click },
	}

	const dataRowOffset = 2

	for i, item := range report.Items {
		for columnTmp, value := range data {
			column := fmt.Sprintf(columnTmp, i+dataRowOffset)

			if err = file.SetCellValue(sheetName, column, value(item)); err != nil {
				return nil, errors.Wrap(err, "set data cell")
			}
		}
	}

	return file, nil
}

func (c *ExcelReportCreator) addHeaderToExcelReport(sheetName string, file *excelize.File) (*excelize.File, error) {
	data := map[string]string{
		"A1": "ID креатива (VI)",
		"B1": "ID креатива (ORD)",
		"C1": "Тип рекламной кампании",
		"D1": "Форма распространения рекламы",
		"E1": "Общее описание объекта рекламирования",
		"F1": "Признак социальной рекламы",
		"G1": "Признак нативной рекламы",
		"H1": "Токен маркировки для креатива",
		"I1": "Дата создания креатива",
		"J1": "ID договора (VI)",
		"K1": "ID договора (ORD)",
		"L1": "Номер договора",
		"M1": "Дата договора",
		"N1": "Сумма договора",
		"O1": "Тип договора",
		"P1": "ID организации клиента (VI)",
		"Q1": "ID организации клиента (ORD)",
		"R1": "Наименование организации клиента",
		"S1": "ИНН организации клиента",
		"T1": "ID организации исполнителя (VI)",
		"U1": "ID организации исполнителя (ORD)",
		"V1": "Наименование организации исполнителя",
		"W1": "ИНН организации исполнителя",
		"X1": "Количество показов",
		"Y1": "Количество переходов",
	}

	for column, value := range data {
		if err := file.SetCellValue(sheetName, column, value); err != nil {
			return nil, errors.Wrap(err, "set header cell value")
		}
	}

	return file, nil
}

@panter-dsd
Copy link

Ah, I've figured it out - the problem was in the unsupported go version 1.21.0. With 1.21.4 it works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs more info This issue can't reproduce, need more info
Projects
None yet
Development

No branches or pull requests

3 participants