Ðекенд за оÑÑеÑи в Delphi, койÑо Ð¾Ñ Ð³Ð¾Ð´Ð¸Ð½Ð¸ генеÑиÑа .xlsx, полÑÑава ново изиÑкване: пÑавилаÑа за обÑеÑÑвени поÑÑÑки на ÐºÐ»Ð¸ÐµÐ½Ñ Ð¾Ñ Ð¿ÑблиÑÐ½Ð¸Ñ ÑекÑÐ¾Ñ Ð¸Ð·Ð¸ÑÐºÐ²Ð°Ñ Ð¸Ð·Ñ Ð¾Ð´ под ÑоÑмаÑа на OpenDocument Spreadsheet, а аналиÑиÑиÑе по Ñази ÑмеÑка изпÑаÑÐ°Ñ ÑедакÑииÑе Ñи обÑаÑно как .ods Ñайлове, запиÑани Ð¾Ñ LibreOffice. Така Ñе Ñега ÑÑÑиÑÑ ÐºÐ¾Ð´ ÑÑÑбва да запиÑва ODS и да го ÑеÑе. HotXLS, оÑигиналнаÑа Object Pascal библиоÑека за елекÑÑонни ÑаблиÑи на losLab за Delphi и C++Builder, Ñе ÑпÑÐ°Ð²Ñ Ð¸ Ñ Ð´Ð²ÐµÑе поÑоки, без никÑде да има инÑÑалиÑан Excel или LibreOffice. Това, коеÑо ÑÑ Ð½Ðµ пÑави, е да напÑави двеÑе поÑоки ÑимеÑÑиÑни. ÐкÑпоÑÑиÑанеÑо пÑенаÑÑ Ð¼Ð½Ð¾Ð³Ð¾ повеÑе, оÑколкоÑо импоÑÑиÑанеÑо вÑзÑÑановÑва, и екип, койÑо пÑедполага обÑаÑноÑо, Ñе наблÑдава как ÑоÑмÑлиÑе и ÑоÑмаÑиÑанеÑо Ñе изпаÑÑÐ²Ð°Ñ Ð½ÑкÑде Ð¼ÐµÐ¶Ð´Ñ ÑедакÑиÑÑа на клиенÑа и ÑледваÑÐ¸Ñ Ð¾ÑÑеÑ, без да има конкÑеÑна гÑеÑка, коÑÑо да го покаже.
ÐоддÑÑжкаÑа на ODS живее вÑв ÑаÑадаÑа XLSX, а не в XLS
HotXLS доÑÑÐ°Ð²Ñ Ð´Ð²Ðµ незавиÑими йеÑаÑÑ
ии Ð¾Ñ ÐºÐ»Ð°Ñове в един пакеÑ: TXLSWorkbook в модÑл (unit) lxHandle за двоиÑни BIFF8 .xls Ñайлове и TXLSXWorkbook в модÑл lxHandleX за OOXML .xlsx пакеÑи. ÐÑÑка вÑ
одна ÑоÑка за OpenDocument - OpenODS, SaveAsODS, GetODSSheetNames - е ÑвÑÑзана Ñ TXLSXWorkbook. Това Ñазположение не е пÑоизволно. ODS пакеÑÑÑ, какÑо е ÑпеÑиÑиÑиÑан в OASIS ODF 1.3, е zip аÑÑ
ив, ÑÑдÑÑÐ¶Ð°Ñ mimetype елеменÑ, маниÑеÑÑ Ð¸ ÑÑло content.xml, коеÑо го пÑави ÑÑÑÑкÑÑÑен бÑаÑовÑед на OOXML zip; BIFF8 е двоиÑен поÑок Ð¾Ñ Ð·Ð°Ð¿Ð¸Ñи Ð¾Ñ 90-Ñе години на Ð¼Ð¸Ð½Ð°Ð»Ð¸Ñ Ð²ÐµÐº, Ñ ÐºÐ¾Ð¹Ñо нÑÐ¼Ð°Ñ Ð½Ð¸Ñо обÑо.
Това Ñазположение има пÑакÑиÑеÑка ÑÑÑана: оÑÑаÑÑла .xls ÑабоÑна книга не може да Ñе пÑевÑÑне в .ods Ñ ÐµÐ´Ð½Ð¾ извикване. ÐÑÑво пÑеÑ
вÑÑлÑÑе ÑÑдÑÑжаниеÑо на BIFF в модела на XLSX ÑÑез SaveXLSWorkbookAsXLSX Ð¾Ñ Ð¼Ð¾Ð´Ñл lxXlsxExport, оÑваÑÑÑе оÑново ÑезÑлÑаÑа пÑез TXLSXWorkbook и Ñлед Ñова екÑпоÑÑиÑаÑе оÑÑам. Този моÑÑ Ð½Ðµ е без загÑба на данни и Ñи ÑÑÑÑва да знаеÑе пÑопÑÑкиÑе, пÑеди да изгÑаждаÑе ÑеÑение вÑÑÑ
Ñ Ð½ÐµÐ³Ð¾. Той копиÑа ÑÑойноÑÑи, ÑоÑмÑли, ÑиÑлови ÑоÑмаÑи, ÑÑиÑÑове, запÑÐ»Ð²Ð°Ð½Ð¸Ñ Ð¸ ÑиÑини на колони. Той изпÑÑка гÑаниÑи, обединени диапазони, коменÑаÑи, диагÑами и ÑÑловно ÑоÑмаÑиÑане. ÐзÑоÑник в .xls Ñ Ñежко ÑоÑмаÑиÑане Ñе доÑÑигне до ODS в по-опÑоÑÑен вид, оÑколкоÑо е бил в наÑалоÑо, и Ñова е ÑвойÑÑво на моÑÑа, а не на ODS пиÑаÑелÑ.
ÐÑкÑиванеÑо Ð¾Ñ ÑÑÑана на импоÑÑиÑанеÑо е авÑомаÑиÑно. ÐбикновениÑÑ Ð¼ÐµÑод Open Ñазпознава ODS пакеÑа по Ð½ÐµÐ³Ð¾Ð²Ð¸Ñ mimetype елеменÑ, каÑо пÑи липÑаÑа Ð¼Ñ Ð¿Ñеминава кÑм пÑовеÑка на най-гоÑно ниво за content.xml, Ñака Ñе Ð¾Ð±Ñ ÐºÐ¾Ð´ Ð¾Ñ Ñипа "оÑвоÑи каквоÑо поÑÑебиÑелÑÑ Ðµ каÑил" не Ñе нÑждае Ð¾Ñ ÑобÑÑвено Ñазпознаване на ÑазÑиÑениÑ. След оÑваÑÑнеÑо ÑвойÑÑвоÑо SourceFormat оÑÑиÑа ÐºÐ¾Ñ Ð¿Ð¾Ñока Ñе е задейÑÑвала.
ÐкÑпоÑÑиÑане кÑм ODS Ñ TODSExportOptions
СамоÑо извикване на екÑпоÑÑ Ðµ на един Ñед; обекÑÑÑ Ñ Ð¾Ð¿Ñии около него ÑÑдÑÑжа ÑеÑениÑÑа, за коиÑо пÑовеÑÑваÑиÑÑ Ñе попиÑа по-кÑÑно:
var
Book: TXLSXWorkbook;
Opts: TODSExportOptions;
begin
Book := TXLSXWorkbook.Create;
try
Book.Open('quarterly-report.xlsx');
Opts := TODSExportOptions.Create; // caller owns and frees this
try
Opts.Generator := 'ReportService 4.2'; // meta:generator override
Opts.IncludeCharts := True;
Opts.IncludeImages := True;
Book.SaveAsODS('quarterly-report.ods', Opts);
finally
Opts.Free;
end;
finally
Book.Free;
end;
end;
ÐбекÑÑÑ Ñ Ð¾Ð¿Ñии е ÑобÑÑвеноÑÑ Ð½Ð° извикваÑÐ¸Ñ ÐºÐ¾Ð´. HotXLS нÑма да го оÑвободи, поÑади коеÑо вÑÑÑеÑниÑÑ Ð±Ð»Ð¾Ðº try..finally е Ñам и е задÑлжиÑелен. ÐвеÑе ÑвойÑÑва, коиÑо пÑоменÑÑ Ð¸Ð·Ñ
одниÑе данни, а не пÑоÑÑо ги еÑикеÑиÑаÑ, заÑлÑÐ¶Ð°Ð²Ð°Ñ Ð¿Ð¾-подÑобен поглед. ÐадаванеÑо на IncludeCharts := False пÑави неÑо повеÑе Ð¾Ñ Ñова да ÑкÑие диагÑамиÑе: Ñо пÑемаÑ
ва поддокÑменÑиÑе на диагÑамиÑе и ÑеÑ
ниÑе запиÑи в маниÑеÑÑа Ð¾Ñ Ð¿Ð°ÐºÐµÑа, коеÑо е ÑоÑно Ñова, коеÑо иÑкаÑе, когаÑо конÑÑмаÑоÑÑÑ Ðµ ÐºÐ¾Ð½Ð²ÐµÐ¹ÐµÑ Ð·Ð° данни, койÑо би Ñе пÑепÑнал в ÑÑÑ
. Generator пÑезапиÑва низа meta:generator на ODF, койÑо инаÑе Ñе ÑеÑе каÑо HotXLS/<version>; пÑезапиÑеÑе го, когаÑо инÑÑÑÑменÑиÑе по веÑигаÑа иденÑиÑиÑиÑÐ°Ñ Ð¿ÑоизводиÑелиÑе на Ñайлове за наÑоÑване на поддÑÑжкаÑа. Ðко ниÑо Ð¾Ñ Ñова не е пÑиложимо, пÑопÑÑнеÑе изÑÑло обекÑа Ñ Ð¾Ð¿Ñии. ÐзвикванеÑо на SaveAs(FileName, xlsxOpenDocumentSpreadsheet) е ÑÑÑоÑо каÑо SaveAsODS Ñ Ð½Ð°ÑÑÑойкиÑе по подÑазбиÑане, а пÑеÑоваÑваниÑÑа Ñ Ð¿Ð¾ÑоÑи (streams) пÑи двеÑе ви позволÑÐ²Ð°Ñ Ð´Ð° запиÑеÑе пакеÑа диÑекÑно в HTTP оÑÐ³Ð¾Ð²Ð¾Ñ Ð±ÐµÐ· вÑеменен Ñайл.
Ðакво ÑеÑе импоÑÑниÑÑ Ð¿ÑÑ Ð¸ какво ÑмиÑлено пÑопÑÑка
ÐÑоÑеÑеÑе Ñази ÑаÑÑ Ð²Ð½Ð¸Ð¼Ð°Ñелно, пÑеди да обеÑаеÑе на нÑкого двÑпоÑоÑна ÑоÑноÑÑ. ÐмпоÑÑиÑанеÑо на ODS в HotXLS е ÑмиÑлено олекоÑен пÑоÑеÑ. То запазва ÑкалаÑниÑе ÑÑойноÑÑи на клеÑкиÑе и кеÑиÑÐ°Ð½Ð¸Ñ ÑезÑлÑаÑ, койÑо вÑÑка ÑоÑмÑла е ноÑила по вÑеме на запиÑванеÑо, и ÑазÑиÑÑва повÑоÑениÑе Ñедове и колони в мÑежаÑа. То не пÑенаÑÑ ÑÑилове, ODS изÑази за ÑоÑмÑли или ÑеÑÑежи.
ÐзбоÑÑÑ Ð·Ð° ÑоÑмÑлиÑе е Ñози, койÑо най-веÑоÑÑно Ñе ви ÑÑздаде пÑоблеми, и Ñой е напÑавен ÑмиÑлено. ÐлеÑка в ODF ÑÑÑ ÑанÑва две неÑа едно до дÑÑго: изÑаза на ÑоÑмÑлаÑа, напиÑан на диалекÑа OpenFormula, деÑиниÑан в ODF 1.3 ЧаÑÑ 4, и поÑледнаÑа ÑÑойноÑÑ, изÑиÑлена за Ð½ÐµÑ Ð¾Ñ Ð³ÐµÐ½ÐµÑиÑаÑоÑо пÑиложение. ÐÑеводÑÑ Ð½Ð° OpenFormula в ÑинÑакÑÐ¸Ñ Ð½Ð° Excel ÑоÑмÑли е ÑобÑÑвен пÑоблем на пÑеобÑазÑване на диалекÑи, Ñ Ñеални гÑаниÑни ÑлÑÑаи около ÑеÑниÑиÑе на ÑÑнкÑииÑе, ÑинÑакÑиÑа на пÑепÑаÑкиÑе и моделиÑе за гÑеÑки. ЧеÑенеÑо на кеÑиÑанаÑа ÑÑойноÑÑ Ð²Ð¼ÐµÑÑо Ñова избÑгва ÑÐµÐ»Ð¸Ñ Ñози ÐºÐ»Ð°Ñ Ð¾Ñ ÑÐ¸Ñ Ð¸ гÑеÑки пÑи пÑевода, Ñака Ñе ÑиÑлаÑа, коиÑо импоÑÑиÑаÑе, Ñа ÑоÑно Ñези, коиÑо изпÑаÑаÑÑÑ Ðµ видÑл поÑледно. ЦенаÑа е, Ñе Ñе пÑиÑÑÐ¸Ð³Ð°Ñ ÐºÐ°Ñо ÑиÑла, а не каÑо акÑивниÑе ÑоÑмÑли, коиÑо Ñа ги генеÑиÑали.
РежимÑÑ Ð½Ð° оÑказ, койÑо ÑÑÑбва да Ñе пÑедвиди пÑи пÑоекÑиÑанеÑо, пÑоизÑиÑа диÑекÑно: елекÑÑонна ÑаблиÑа, ÑииÑо обÑи ÑÑми Ñа били пÑавилни, когаÑо LibreOffice Ñ Ðµ запиÑал поÑледно, Ñе импоÑÑиÑа Ñ Ð¿Ñавилни ÑиÑла, но Ñези ÑиÑла веÑе Ñа конÑÑанÑи. РедакÑиÑайÑе вÑ
одÑÑа клеÑка, пÑеизÑиÑлеÑе и ниÑо нÑма да Ñе пÑомени - ÑоÑмÑлаÑа Ñ Ð½Ñма, оÑÑанал е Ñамо кÑайниÑÑ Ð¹ ÑезÑлÑаÑ. Ðко ÑабоÑниÑÑ Ð¿ÑоÑÐµÑ Ñе нÑждае Ð¾Ñ Ð°ÐºÑивни ÑоÑмÑли Ñлед импоÑÑиÑанеÑо, вÑзÑÑановеÑе ги пÑогÑамно Ð¾Ñ Ð²Ð°ÑиÑе ÑобÑÑвени Ð±Ð¸Ð·Ð½ÐµÑ Ð¿Ñавила ÑÑез Cell.Formula, коеÑо вÑв ÑаÑадаÑа XLSX пÑиема изÑаза без Ð²Ð¾Ð´ÐµÑ Ð·Ð½Ð°Ðº за ÑавенÑÑво.
ÐÑоекÑиÑане около аÑимеÑÑиÑÐ½Ð¸Ñ Ð´Ð²ÑпоÑоÑен пÑеноÑ
ÐкÑпоÑÑиÑанеÑо ÑендиÑа Ð¾Ñ Ð¿ÑÐ»Ð½Ð¸Ñ Ð¼Ð¾Ð´ÐµÐ» на ÑабоÑнаÑа книга в памеÑÑа: ÑÑойноÑÑи, ÑÑилове и, ако ги поиÑкаÑе, диагÑами и изобÑажениÑ. ÐмпоÑÑиÑанеÑо вÑÑÑа Ñамо ÑÑойноÑÑи. Така Ñе еÑапÑÑ Ð¾Ñ .xlsx кÑм .ods е Ñ Ð²Ð¸Ñока ÑоÑноÑÑ, а еÑапÑÑ Ð¾Ñ .ods кÑм .xlsx вÑÑÑа ÑÑойноÑÑи и кеÑиÑани ÑезÑлÑаÑи, но без ÑÑилизиÑане и без акÑивни ÑоÑмÑли. СвÑÑжеÑе двеÑе и аÑимеÑÑиÑÑа Ñе задÑлбоÑава. ÐÑлен ÑикÑл Ð¾Ñ .xlsx кÑм .ods и обÑаÑно кÑм .xlsx запиÑва вÑиÑко вÑÑно на излизане и гÑби ÑÑиловеÑе и ÑоÑмÑлиÑе на влизане, вÑпÑеки Ñе ниÑо не Ñе е пÑовалило пÑи ниÑо една Ð¾Ñ ÑÑÑпкиÑе.
Book := TXLSXWorkbook.Create;
try
Book.Open('vendor-revision.ods'); // format auto-detected
if Book.SourceFormat = xlsxOpenDocumentSpreadsheet then
begin
// Values and cached formula results are present after an ODS
// import; styles and live formulas are not. Rebuild whatever
// the downstream pipeline depends on before saving.
Book.Sheets[0].Cells[2, 5].Formula := 'SUM(B2:D2)';
Book.SaveAs('vendor-revision.xlsx');
end;
finally
Book.Free;
end;
ÐÑÑ Ð¸ÑекÑÑÑниÑÑ Ð¼Ð¾Ð´ÐµÐ», койÑо пÑоизÑиÑа Ð¾Ñ Ñова: ÑÑеÑиÑайÑе Ð²Ñ Ð¾Ð´ÑÑиÑе .ods Ñайлове каÑо канали за данни, а не каÑо докÑменÑи за ÑедакÑиÑане на мÑÑÑо. ÐоддÑÑжайÑе канониÑнаÑа ÑабоÑна книга в .xlsx, ÑеÑеÑе ÑÑойноÑÑиÑе Ð¾Ñ ÑедакÑииÑе на клиенÑиÑе и излÑÑвайÑе нов ODS пÑи поиÑкване Ð¾Ñ ÐºÐ°Ð½Ð¾Ð½Ð¸ÑноÑо копие. ÐеÑиÑикаÑиÑÑа пÑинадлежи и на дваÑа лагеÑа - оÑваÑÑйÑе екÑпоÑÑиÑаниÑе Ñайлове в LibreOffice Calc, еÑÐ°Ð»Ð¾Ð½Ð½Ð¸Ñ Ð¿Ð¾ÑÑебиÑел на ODF, и в Excel, койÑо ÑеÑе ODS Ð¾Ñ Ð³Ð¾Ð´Ð¸Ð½Ð¸, но Ñе Ñазминава Ñ LibreOffice по гÑаниÑиÑе на поддÑÑжкаÑа на диагÑами и ÑÑилове. ÐÑоÑÑ Ð½Ð° лиÑÑовеÑе, Ñепа клÑÑови клеÑки и налиÑиеÑо на диагÑами пÑавÑÑ Ð´Ð¾ÑÑаÑÑÑна бÑÑза пÑовеÑка (smoke check) за вÑеки екÑпоÑÑен пÑоÑил.
ТÑиаж на ODS Ñайл пÑеди ангажиÑане Ñ Ð¸Ð¼Ð¿Ð¾ÑÑиÑане
ÐогаÑо дадена кÑайна ÑоÑка пÑиема каÑваниÑ, ÑпиÑванеÑо на именаÑа на лиÑÑовеÑе е много по-евÑино Ð¾Ñ Ð¿Ñлен паÑÑ Ð¸ ÑÐ»Ð°Ð²Ñ ÑÑÑÑкÑÑÑни изненади Ñано:
Names := TStringList.Create;
Book := TXLSXWorkbook.Create;
try
if Book.GetODSSheetNames('incoming.ods', Names) <= 0 then
raise Exception.Create('not a readable ODS package');
if Names.IndexOf('Data') < 0 then
raise Exception.Create('revision is missing the Data sheet');
finally
Book.Free;
Names.Free;
end;
ÐонвенÑиÑÑа за вÑÑÑане на ÑезÑлÑÐ°Ñ Ð¾Ð±ÑÑква Ñ
оÑаÑа: извикваниÑÑа на HotXLS обикновено вÑÑÑÐ°Ñ Ð¿Ð¾Ð»Ð¾Ð¶Ð¸Ñелен бÑой или 1 пÑи ÑÑпеÑ
и -1 пÑи неÑÑпеÑ
, каÑо изÑиÑÑÐ²Ð°Ñ ÑпиÑÑка пÑи неÑÑпеÑ
, Ñака Ñе ÑеÑÑвайÑе за <= 0, вмеÑÑо да ÑÑавнÑваÑе Ñ ÐµÐ´Ð½Ð° конкÑеÑна положиÑелна ÑÑойноÑÑ. GetODSSheetNames ниÑо нÑлиÑа, ниÑо попÑлва инÑÑанÑиÑÑа на ÑабоÑнаÑа книга, Ñака Ñе единиÑен Ð¾Ð±ÐµÐºÑ Ð·Ð° ÑондиÑане може да пÑовеÑи ÑÑла диÑекÑоÑÐ¸Ñ Ñ Ð²Ñ
одÑÑи Ñайлове. СÑÑÑкÑÑÑни пÑовеÑки каÑо Ñази ÑлавÑÑ Ð½Ð°Ð¹-ÑеÑÑо ÑÑеÑÐ°Ð½Ð¸Ñ Ð¿Ñовал в ÑÐµÐ°Ð»Ð½Ð¸Ñ ÑвÑÑ - аналиÑик, койÑо пÑеименÑва или изÑÑива лиÑÑ, пÑеди да изпÑаÑи ÑедакÑиÑÑа обÑаÑно - оÑе на вÑ
ода, кÑдеÑо ÑÑобÑениеÑо за гÑеÑка вÑе оÑе може да назове Ñайла и липÑваÑÐ¸Ñ Ð»Ð¸ÑÑ, вмеÑÑо да Ñе поÑви каÑо nil пÑепÑаÑка ÑÑи ÑÐ»Ð¾Ñ Ð¿Ð¾-дÑлбоко.
Ðко изгÑаждаÑе по-ÑиÑок ÐºÐ¾Ð½Ð²ÐµÐ¹ÐµÑ Ð·Ð° пÑеобÑазÑване около Ñова, моделÑÑ Ð½Ð° ÑабоÑен Ð¿Ð»Ð¾Ñ Ð·Ð° Ð¾Ð´Ð¸Ñ Ð¸ пÑеобÑазÑване на ÑабоÑни книги показва как да напÑавиÑе Ð¾Ð¿Ð¸Ñ Ð½Ð° Ñ Ð°ÑакÑеÑиÑÑикиÑе на Ñайла, пÑеди да избеÑеÑе ÑÐµÐ»ÐµÐ²Ð¸Ñ ÑоÑмаÑ, а ÑÑководÑÑвоÑо за пÑоизводиÑелноÑÑ Ð¿Ñи големи ÑабоÑни книги поддÑÑжа пакеÑниÑе екÑпоÑÑи в ÑазÑмни гÑаниÑи на памеÑÑа.
HotXLS е оÑигинална библиоÑека за елекÑÑонни ÑаблиÑи за Delphi и C++Builder Ñ Ð¿Ñлен Ð¸Ð·Ñ Ð¾Ð´ÐµÐ½ код; пÑлниÑÑ ÑпиÑÑк Ñ ÑÑнкÑии и подÑобноÑÑи за лиÑензиÑанеÑо Ñа на ÑÑÑаниÑаÑа на пÑодÑкÑа HotXLS Component.