0

We host our web forms app on a Windows server.

We utilize SpreadSheetGear to write formulas to cells and allow the user to download the workbook.

We determine the list separator by the Server culture (this is a problem).

We service customers in USA and Latin America.

All this adds up to us providing the wrong List Separator for Latin America machines. The server culture doesn't match the user culture, so SpreadSheetGear throws an Invalid Formula error when we try to .Formula a cell with an improper separator.

I can't find a way to get the separator from the local machine. Accept-Language on the HTTP header passes me multiple languages with weighted values, but this is still guesswork.

My solution was to create a workbook and try to write to a cell on that new workbook. If it fails, the separator is a comma, otherwise, it's a semi-colon.

The concern with this logic is that we call ExcelValueSeparator often, and each time we do, we'd be creating and disposing of a new workbook, worksheet, etc. We're concerned about speed.

I've attached a screenshot of my new logic.

Does anyone here have a better way to accomplish this without guesswork? Are our speed concerns here warranted?

enter image description here

w2-
  • 19
  • 5

1 Answers1

1

If you have full control of the workbook-creating and formula-creating process on your server (i.e., your end-users from other parts of the globe don't provide potentially culture-sensitive function or formula strings), and if your end-user's are receiving a downloadable Excel file such as XLSX, XLSM or XLS from their browser, then to me it sounds like you can simplify your server-side approach by ensuring you always create the workbook using an "en-US" CultureInfo object and adhere to en-US conventions (such as using a comma as the list separator) when constructing your formulas.

Reason being is that these CultureInfo-specific aspects of a workbook such as ListSeparator are only relevant at runtime--when the workbook file is actually opened in SpreadsheetGear, or Excel for that matter. Once a workbook is stored on disk (or stream form when sending to an end-user's browser), it's essentially stored in that file in a "locale-neutral" manner. It's not until the file is subsequently opened under a given regional environment (i.e., in Excel they look at the OS regional settings; in SpreadsheetGear we look at the CultureInfo you pass in) that locale-sensitive things like the list separator character (and other things like date formats, currency character, etc.) are dynamically applied to the workbook.

So in the case of your Latin American customers, the Excel workbook which was "en-US" on the server during runtime, will take on whatever locale conventions they might be running on their machines once they open it in Excel.

To ensure you use "en-US" when working on a file in SpreadsheetGear (and provide some assurance that you can always use a comma for the ListSeparator), you can either explicitly pass that CultureInfo in, or just don't pass anything in, as that's what is used by default. Example:

// These are functionally the same.
IWorkbook workbook = Factory.GetWorkbook();
IWorkbook workbook = Factory.GetWorkbook(System.Globalization.CultureInfo.GetCultureInfo("en-US"));
Tim Andersen
  • 3,014
  • 1
  • 15
  • 11
  • I need to do some more testing, Tim, but I believe the latter of that code is working. I've had a successful print with it. I did not get a successful print when I passed nothing to GetWorkbook. It failed still. We're working multiple angles here, so I'm going to confirm before I mark this. Thank you! – w2- Sep 24 '20 at 19:30
  • 1
    I can say with certainty that either overload of Factory.GetWorkbook() mentioned above will use "en-US". It's documented here: https://www.spreadsheetgear.com/support/help/spreadsheetgear.net.8.0/#SpreadsheetGear2017~SpreadsheetGear.Factory~GetWorkbook().html and I double-checked the source code to ensure this is the case (SpreadsheetGear is not open source but I work for SpreadsheetGear and so can check it). I can't explain why each method might cause your app to behave in different ways, but there must be something else going on here. – Tim Andersen Sep 24 '20 at 19:39
  • Forcing the culture works globally from what I can tell. We're pushing to Alpha to test on the servers. I marked your response as the answer. I'll add this caveat. This technically should have never failed according to the findings between you and I, Tim, and our original code. Our servers are all en-US, and I confirmed we were getting en-US in the debugger while we were still failing. :shrug: I'm happy with the fix, either way. Thanks for your help! :) – w2- Sep 24 '20 at 20:59
  • 1
    An edge-case where "en-US" might still fail is where your machine was setup with "en-US" in the regional settings, but you customized the "List separator" field in the Control Panel dialogs to use a semi-colon instead. In your original code you passed in System.Globalization.CultureInfo.CurrentCulture which is technically "en-US"; however, SpreadsheetGear would pick up the custom semi-colon. So attempting to use a comma as the list separator in a formula would fail in this case. Passing in GetCultureInfo("en-US") or omitting any CultureInfo ought to give you a plain vanilla en-US CultureInfo. – Tim Andersen Sep 24 '20 at 21:35
  • 1
    Also note there is an `IWorkbook.WorkbookSet.Culture` property that returns the CultureInfo object being used for the workbook set. So once you have this, you could check `CultureInfo.TextInfo.ListSeparator` to definitively know what list separator SpreadsheetGear would require. – Tim Andersen Sep 24 '20 at 21:35
  • I tested the edge case with my changes and it still worked. In fact, I'm not sure I tested these changes locally with my region list separator set to comma. I think it was semi-colon the whole time after your suggestion above. Thanks for your excellent service, Tim. Your managers should give you a raise. I have one last question. Do you guys have a Discord or a Slack server I could get an invite to? – w2- Sep 24 '20 at 21:39
  • 1
    Haha, I'd never turn down a raise :) We don't have Slack or Discord or anything like that, unfortunately. But I do actively monitor the [spreadsheetgear] tag here on SO, and do my best to respond when I can. Active subscribers to SpreadsheetGear products (or evaluators for 30 days) can also email / call us directly for tech support. We do our best to respond as quickly as possible (definitely same-day, often within an hour or minutes for simple inquiries) during work hours. – Tim Andersen Sep 24 '20 at 21:46