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

Delphi 2007 #33

Open
MtwStark opened this issue Jan 10, 2020 · 4 comments
Open

Delphi 2007 #33

MtwStark opened this issue Jan 10, 2020 · 4 comments

Comments

@MtwStark
Copy link
Contributor

MtwStark commented Jan 10, 2020

Is it possible to set a cell to a unicode string value in delphi 2007 where string type is AnsiString?

MyWideString := 'сатри санҷиши юникод';
MyCell.AsString := MyWideString;

but in result xlsx MyCell will get '????? ??????? ??????'

@the-Arioch
Copy link
Contributor

the-Arioch commented Feb 12, 2020

Option 1: Try explicit pre-conversion: MyCell.Data := UTF8Encode(MyWideString);
This should be the most universal but very boring and fragile solution.
Perhaps the only one, if you really need different MVCS codepagesand can not set on the only one.

Option 2: If one non-unicode codepage is enough, then try explicitly specifying that non-UTF-8 codepage when saving XLSX. This way, the MyCell.Data := 'dsfsfsfsdfdsfdsfdsfds'; assignments are done as usual.

Below is the code from Delphi 2006 project.

The project uses Russian Windows codepage (1251).
In your case there probably would be another codepage.
Most probably one, returned by GetACP() Windows function.

uses zeSave;
// the project also should somewhere has `uses zeSaveXLSX` 
// the project also should somewhere has one of `uses zeZippyXXXX` - i'd use WinXP for early Delphi

     zxBook := TZEXMLSS.Create(....);

// generate report

      zxBook.SuppressedCellWarnings := [zvwNumbersAsText, zvw2DigitsYear];
      IntResult := TZXMLSSave.From(zxBook).Charset(1251).TO_(SaveToFile).Save;
      if(IntResult = 0) then
      begin
        OpenExcelApplication(SaveToFile);
      end {= if =};

Avemey, could you please put this snippet into some FAQ or at least mention in ReadMe ?

@MtwStark
Copy link
Contributor Author

MtwStark commented Feb 12, 2020

Hi, I have solved implementing WideString support depending on define DELPHI_UNICODE

in zsspxml.pas I have overloaded
WriteRaw, all versions of WriteTag, CheckStrEntity and Correct_Entity with a WideString version

in ZEGetDefaultUTF8Converter I have bypassed @AnsiToUTF8 returning nil

P.S.
in all versions of CheckStrEntity I had to add a filter for unsupported characters:
#0..#31 (except #9, #10, #13), #127, #129, #141, #143, #144, #157
Also #160 replaced with a #32

in zexmlss.pas
I have simply conditioned property Data (and all related variables and functions) to be WideString instead of string

Now it works like a charm in D2007

@the-Arioch
Copy link
Contributor

I have simply conditioned property Data (and all related variables and functions) to be WideString
Which means you now have your own fork that way, partially incompatible with mainstream and only custom-tailored for one specific project and compiler of yours.

Since FPC is more important than Delphi to Avemey i do not think he would go that way.
Additionally, if these your changes were not isolated into a separate branch, they would start leaking into your master, which would probably mean Avemey would not be able to accept your pull requests on other features.

Also, using BSTR type means you multiplied memory use many times. We might expect that old Delphi is used on old computers, where RAM and CPU speed as not in such excess as on modern computers.

Perhaps a correct way would be declaring a type like TZString, and mapping it to different real types, dependent upon compiler used. TZString=UnicodeString on Delphi 2009+, =AnsiString on Delphi 2007-, =UTF8String on FPC

But even this would still mean RAM usage might get hugely multiplicated using WideString, so i wonder if that solution is universal.

Also #160 replaced with a #32

For example i would definitely prohibit this in MY project

@MtwStark
Copy link
Contributor Author

In zsspxml.pas there is already the overloaded version conditioned by DELPHI_UNICODE define, I have only extended it.

If DELPHI_UNICODE is defined string type is already WideString so, in zexmlss.pas, in TZCell class, changing:

FData: string;

with:

{$IFDEF DELPHI_UNICODE}
FData: string;
{$ELSE}
FData: WideString;
{$ENDIF}

should not create a problem for newer Delphi.

Also, putting invalid characters in an excel cell will result in an error when opening the document, so I think that filtering them should be done.

#160 is the   (non breaking space) but is invalid in excel cell, so in my opinion the choice is between filtering it or replacing with a normal space.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants