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

Supports streaming write. #1739

Closed
xiwh opened this issue Dec 1, 2023 · 4 comments
Closed

Supports streaming write. #1739

xiwh opened this issue Dec 1, 2023 · 4 comments
Labels
duplicate This issue or pull request already exists

Comments

@xiwh
Copy link

xiwh commented Dec 1, 2023

Description

When exporting a large dataset, the browser takes a while to show the download dialog.

Steps to reproduce the issue:

func Export(w http.ResponseWriter, req *http.Request) {
	w.Header().Set("Content-Type", "application/octet-stream")
	w.Header().Set("Content-Disposition", "attachment;filename=export.xlsx")
	w.Header().Set("Content-Transfer-Encoding", "binary")
	w.(http.Flusher).Flush()

	f := excelize.NewFile()
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()
	sw, err := f.NewStreamWriter("Sheet1")
	if err != nil {
		fmt.Println(err)
		return
	}
	styleID, err := f.NewStyle(&excelize.Style{Font: &excelize.Font{Color: "777777"}})
	if err != nil {
		fmt.Println(err)
		return
	}
	if err := sw.SetRow("A1",
		[]interface{}{
			excelize.Cell{StyleID: styleID, Value: "Data"},
			[]excelize.RichTextRun{
				{Text: "Rich ", Font: &excelize.Font{Color: "2354e8"}},
				{Text: "Text", Font: &excelize.Font{Color: "e83723"}},
			},
		},
		excelize.RowOpts{Height: 45, Hidden: false}); err != nil {
		fmt.Println(err)
		return
	}
	for rowID := 2; rowID <= 1000000; rowID++ {
		row := make([]interface{}, 50)
		for colID := 0; colID < 50; colID++ {
			row[colID] = rand.Intn(640000)
		}
		cell, err := excelize.CoordinatesToCellName(1, rowID)
		if err != nil {
			fmt.Println(err)
			break
		}
		if err := sw.SetRow(cell, row); err != nil {
			fmt.Println(err)
			break
		}
	}
	if err := sw.Flush(); err != nil {
		fmt.Println(err)
		return
	}
	_ = f.Write(w)
}

Describe the results you received:

Describe the results you expected:

Output of go version:

go version go1.19.2 windows/amd64

Excelize version or commit ID:

v2.7.1

Environment details (OS, Microsoft Excel™ version, physical, etc.):

@xuri
Copy link
Member

xuri commented Dec 4, 2023

Thanks for your issue. You already using the stream writer in your code. What's your received and whats the results you expected? Could you follow the issue template to provide more details about this?

@xuri xuri added the needs more info This issue can't reproduce, need more info label Dec 4, 2023
@xiwh
Copy link
Author

xiwh commented Dec 4, 2023

Thanks for your issue. You already using the stream writer in your code. What's your received and whats the results you expected? Could you follow the issue template to provide more details about this?

Thank you for your support. It appears I didn't explain it clearly. What I aim to achieve is to progressively write to http.ResponseWriter when calling sw.Flush(). Currently, when exporting large files, we have to wait for the entire write operation to finish, leading to a substantial delay before the browser displays the file download dialog

@xuri
Copy link
Member

xuri commented Dec 4, 2023

Thanks for your details. This is similar to issues #753 and #1052. The workbook serialization should be waiting for all worksheets has be ready. Maybe an asynchrony download design will be better for generating a large workbook.

@xuri xuri added duplicate This issue or pull request already exists and removed needs more info This issue can't reproduce, need more info labels Dec 4, 2023
@xiwh
Copy link
Author

xiwh commented Dec 4, 2023

Thanks for your details. This is similar to issues #753 and #1052. The workbook serialization should be waiting for all worksheets has be ready. Maybe an asynchrony download design will be better for generating a large workbook.

Thank you for your response. I have found an alternative solution by triggering the download dialog through JavaScript using XMLHttpRequest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

2 participants