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

GSheet can't use Tables when xlsx file generated by Excelize #1314

Closed
simulot opened this issue Aug 10, 2022 · 11 comments
Closed

GSheet can't use Tables when xlsx file generated by Excelize #1314

simulot opened this issue Aug 10, 2022 · 11 comments
Labels
confirmed This issue can be reproduced

Comments

@simulot
Copy link

simulot commented Aug 10, 2022

Description
I'm using excelize to produce read and write workbook around an entreprise application.
I'm using Table feature to get a convient sheet with banded rows. This works on Excel and GSheet (with limitations). GSheet is mandatory because many of users don't have Excel.

Generated files are opened by GSheet, by all Table definitions are removed.
In another hand, the same file is correctly handled by Excel (2016). Tables are rendered. Saving the same file from excel makes GSheet accepting Tables and render them as "Alternating colors".

Steps to reproduce the issue:

  1. Create the table
    f.AddTable(sheet, "A1","D6", { "table_name": "Report", "table_style": "TableStyleMedium1", "show_first_column": 0, "show_last_column": 0, "show_row_stripes": 1, "show_column_stripes": 0 })
  2. Save the file into a google drive

Describe the results you received:
image

Describe the results you expected:
image

Color schemas isn't good (GSheet issue), but headers are present.

Output of go version:

go1.19 windows/amd64

Excelize version or commit ID:

github.com/xuri/excelize/v2 v2.6.0

Environment details (OS, Microsoft Excel™ version, physical, etc.):
Windows 10
Google Sheet current
Excel 2016

@xuri
Copy link
Member

xuri commented Aug 10, 2022

Thanks for your feedback. Please receive and check the error returned by the AddTable function, you need to use the right data type for each field in the table properties JSON like this:

{
    "table_name": "Report",
    "table_style": "TableStyleMedium1",
    "show_first_column": false,
    "show_last_column": false,
    "show_row_stripes": true,
    "show_column_stripes": false
}

and it will be working as your expected in the Google Sheet.

@simulot
Copy link
Author

simulot commented Aug 10, 2022

You're right...
I have compared table file inside the XLSX and found that booleans are stored as true/false in excelize, but as 0 and 1 in Excel.

Using 0 and 1 with standard release gives errors.
So I have forked your code to do test if it was the cause problem. But's it doesn't change the problem.
I forget to switch back to the official release before copying the code. Sorry.

Anyway, opening the file using excel, save it is enough to get it working in GSheet. This is easy, but its ruins the possibility to have a fully automatized process.

@xuri
Copy link
Member

xuri commented Aug 10, 2022

The booleans value storage in the XML is not the reason for this problem, I mean that you need to use the true or false in the show_first_column, show_last_column fields when you call the AddTable function of the Excelize. If you are using the 0 or 1, there is an error that would be returned, the table has not been added to the worksheet, so you can't see it when your upload and open the generated workbook on Google Sheet.

@simulot
Copy link
Author

simulot commented Aug 10, 2022

Agreed, but this isn't the problem.

Here is the test code:

package main

import (
	"fmt"
	"os"

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

var (
	sample = [][]any{
		{"User", "Age", "Country", "Color"},
		{"John", 25, "Green"},
		{"Tom", 10, "Yellow"},
		{"Mary", 25, "Green"},
		{"Lin", 20},
		{"Ted", 20, "Red"},
	}
	sampleAbsTopLeft     = checkError(excelize.CoordinatesToCellName(1, 1, true))
	sampleAbsBottomRight = checkError(excelize.CoordinatesToCellName(len(sample[0]), len(sample), true))
)

func checkError[T any](v T, err error) T {
	if err != nil {
		exitOnError(err)
	}
	return v
}

func exitOnError(err error) {
	if err != nil {
		fmt.Println("Error:", err.Error())
		os.Exit(1)
	}
}

func main() {

	sheet := "Test1"
	f := excelize.NewFile()

	f.NewSheet(sheet)
	for r, row := range sample {
		for c, cell := range row {
			exitOnError(f.SetCellValue(sheet, checkError(excelize.CoordinatesToCellName(c+1, r+1)), cell))
		}
	}
	exitOnError(f.AddTable(sheet, sampleAbsTopLeft, sampleAbsBottomRight, fmt.Sprintf(`{
		"table_name": "_%s",
		"table_style": "TableStyleMedium12",
		"show_first_column": false,
		"show_last_column": false,
		"show_row_stripes": true,
		"show_column_stripes": false
	}`, "_"+sheet)))
	f.DeleteSheet("Sheet1")
	exitOnError(f.SaveAs(sheet + ".xlsx"))
}

Here the generated file.

Test1.xlsx

Place it into google drive and open it
Now, open the original with excel, save it (just move the active cell), place it into google drive and open it again in google sheet.

@xuri xuri added the confirmed This issue can be reproduced label Aug 12, 2022
@xuri
Copy link
Member

xuri commented Aug 12, 2022

After investigation, the reason for this issue was the same as #1244.

@xuri xuri closed this as completed in 551fb8a Aug 13, 2022
@xuri
Copy link
Member

xuri commented Aug 13, 2022

This issue has been fixed, please upgrade to the master branch code, and this patch will be released in the next version.

@simulot
Copy link
Author

simulot commented Aug 13, 2022

Thank you for this quick answer

I have tested the new version:
The table loads with named ranges and data validation based on list or named range.

But I have found following:

  • The style of the table (ex: TableStyleMedium12) is lost, the table is rendered without colors
  • All conditional formatting is lost. (use vlookup over named ranges)

The loading and saving files in excel makes conditional formatting working.

@xuri
Copy link
Member

xuri commented Aug 13, 2022

Please upgrade to the master branch. I've tested with your provides code (which using the TableStyleMedium12 theme color for the table), and the table was in yellow theme when open the generated workbook in Google Sheet. There are no conditional formatting in this workbook. Could you show us a complete, standalone example program or reproducible demo?

@simulot
Copy link
Author

simulot commented Aug 13, 2022

With the following version;

require github.com/xuri/excelize/v2 v2.6.1-0.20220813032159-551fb8a9e4b0

I get following:

Simple sheet with conditional formatting:

Excel:
image

GSheet:
image

Same data with conditional formatting and a Table:

Excel:
image

GSheet:
image

The test code:

package main

import (
	"fmt"
	"os"

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

var (
	sample = [][]any{
		{"User", "Age", "Color"},
		{"John", 25, "Green"},
		{"Tom", "", "Yellow"},
		{"Mary", 25, "Green"},
		{"Lin", 20},
		{"Ted", 20, "Red"},
	}
	sampleAbsTopLeft     = checkError(excelize.CoordinatesToCellName(1, 1, true))
	sampleAbsBottomRight = checkError(excelize.CoordinatesToCellName(len(sample[0]), len(sample), true))
)

func checkError[T any](v T, err error) T {
	if err != nil {
		exitOnError(err)
	}
	return v
}

func exitOnError(err error) {
	if err != nil {
		fmt.Println("Error:", err.Error())
		os.Exit(1)
	}
}

func main() {
	test1()
	test2()
}

func test1() {
	sheet := "Test1"
	f := excelize.NewFile()

	f.NewSheet(sheet)
	for r, row := range sample {
		for c, cell := range row {
			exitOnError(f.SetCellValue(sheet, checkError(excelize.CoordinatesToCellName(c+1, r+1)), cell))
		}
	}
	format := checkError(f.NewConditionalStyle(`{
		"font":
		{
			"color": "#9A0511"
		},
		"fill":
		{
			"type": "pattern",
			"color": ["#FEC7CE"],
			"pattern": 1
		}
	}`))

	exitOnError(f.SetConditionalFormat(sheet, sampleAbsTopLeft+":"+sampleAbsBottomRight, fmt.Sprintf(`[
		{
			"type": "formula",
			"criteria": "=A1=\"\"",
			"format": %d
		}]`, format)))

	f.DeleteSheet("Sheet1")
	exitOnError(f.SaveAs(sheet + ".xlsx"))
}

func test2() {
	sheet := "Test2"
	f := excelize.NewFile()

	f.NewSheet(sheet)
	for r, row := range sample {
		for c, cell := range row {
			exitOnError(f.SetCellValue(sheet, checkError(excelize.CoordinatesToCellName(c+1, r+1)), cell))
		}
	}
	format := checkError(f.NewConditionalStyle(`{
		"font":
		{
			"color": "#9A0511"
		},
		"fill":
		{
			"type": "pattern",
			"color": ["#FEC7CE"],
			"pattern": 1
		}
	}`))

	exitOnError(f.SetConditionalFormat(sheet, sampleAbsTopLeft+":"+sampleAbsBottomRight, fmt.Sprintf(`[
		{
			"type": "formula",
			"criteria": "=A1=\"\"",
			"format": %d
		}]`, format)))

	exitOnError(f.AddTable(sheet, sampleAbsTopLeft, sampleAbsBottomRight, fmt.Sprintf(`{
		"table_name": "_%s",
		"table_style": "TableStyleMedium12",
		"show_first_column": false,
		"show_last_column": false,
		"show_row_stripes": true,
		"show_column_stripes": false
	}`, "_"+sheet)))

	f.DeleteSheet("Sheet1")
	exitOnError(f.SaveAs(sheet + ".xlsx"))
}

@xuri xuri reopened this Aug 15, 2022
@xuri
Copy link
Member

xuri commented Aug 15, 2022

Please remove the equal symbol in the conditional formatting formula, using the "A1=\"\"" instead of "=A1=\"\"".

@xuri xuri closed this as completed Aug 15, 2022
@simulot
Copy link
Author

simulot commented Aug 17, 2022

Correct. Sorry for the noise.
Thanks for your help.

rodoard pushed a commit to sheetrocks/excelize that referenced this issue Aug 26, 2022
…bility with Google Sheet

- Format code with `gofmt`
xuri added a commit to carbin-gun/excelize that referenced this issue Oct 9, 2022
…bility with Google Sheet

- Format code with `gofmt`
xuri added a commit to JDavidVR/excelize that referenced this issue Jul 11, 2023
…bility with Google Sheet

- Format code with `gofmt`
jenbonzhang pushed a commit to jenbonzhang/excelize that referenced this issue Oct 22, 2023
…bility with Google Sheet

- Format code with `gofmt`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed This issue can be reproduced
Projects
None yet
Development

No branches or pull requests

2 participants