ÐонÑкога единÑÑвениÑÑ Ð²ÑпÑоÑ, на койÑо вÑ
одÑÑаÑа ÑÑÑина ÑÑÑбва да оÑговоÑи, е ÑÑÑÑкÑÑÑен: има ли Ñази ÑабоÑна книга лиÑÑ, наÑеÑен "Mapping", или колко Ñаздели (tabs) ÑÑдÑÑжа ÑÑ. ÐÑговоÑÑÑ Ð½Ð° Ñова ÑÑез извикване на Open е ÑкÑпиÑÑ Ð½Ð°Ñин да го напÑавиÑе. ÐÑлноÑо оÑваÑÑне ÑазÑиÑÑва ÑаблиÑаÑа за Ñподелени низове (shared string table), декодиÑа вÑеки Ð·Ð°Ð¿Ð¸Ñ Ð·Ð° ÑÑил и обÑ
ожда клеÑкиÑе на вÑеки ÑабоÑен лиÑÑ, ÑÑй каÑо нÑма как да знае, Ñе ÑÑе иÑкали Ñамо ÑÑдÑÑжаниеÑо. ÐÑи голÑм Ñайл Ñова ознаÑава ÑÑоÑиÑи мегабайÑи заделена Ð¿Ð°Ð¼ÐµÑ Ð¸ нÑколко ÑекÑнди пÑоÑеÑоÑно вÑеме, изÑазÑ
одвани за ÑеÑене на ÑпиÑÑк, койÑо заема нÑколко килобайÑа. HotXLS, оÑигиналнаÑа Delphi библиоÑека за елекÑÑонни ÑаблиÑи на losLab, ви дава Ñози ÑпиÑÑк ÑамоÑÑоÑÑелно: GetSheetNames вÑÑÑа именаÑа на ÑабоÑниÑе лиÑÑове в Ñеда на ÑабоÑнаÑа книга, без да визÑализиÑа ниÑо една клеÑка.
ÐаÑо каÑалогÑÑ Ðµ евÑин за ÑеÑене
РдваÑа ÑоÑмаÑа за елекÑÑонни ÑаблиÑи поÑÑавÑÑ ÑвоеÑо ÑÑдÑÑжание близо до наÑалоÑо, коеÑо пÑави извикванеÑо за избÑоÑване бÑÑзо, а не Ñложно. ÐакеÑÑÑ OOXML ÑÑÑ
ÑанÑва каÑалога на лиÑÑовеÑе в xl/workbook.xml - ÑаÑÑ, коÑÑо оÑÑава малка незавиÑимо дали ÑабоÑнаÑа книга ÑÑдÑÑжа деÑÐµÑ Ñеда или деÑÐµÑ Ð¼Ð¸Ð»Ð¸Ð¾Ð½Ð°. ÐвоиÑниÑÑ .xls вÑв ÑоÑÐ¼Ð°Ñ BIFF8 ÑÑÑ
ÑанÑва ÑвоиÑе BoundSheet запиÑи в наÑалоÑо на Ð³Ð»Ð¾Ð±Ð°Ð»Ð½Ð¸Ñ Ð¿Ð¾Ñок на ÑабоÑнаÑа книга, пÑеди каквиÑо и да било данни за клеÑки. Така Ñе ÑабоÑаÑа, коÑÑо извикванеÑо за ÑпиÑване избÑгва, не е гÑеÑка Ð¾Ñ Ð·Ð°ÐºÑÑглÑне ÑпÑÑмо пÑлноÑо оÑваÑÑне. Това е по-голÑмаÑа ÑаÑÑ Ð¾Ñ Ñайла. ЧеÑенеÑо на каÑалога ÑÑÑÑва ÑÑÑиÑе нÑколко килобайÑа незавиÑимо Ð¾Ñ Ð±ÑÐ¾Ñ Ð½Ð° ÑедовеÑе, докаÑо пÑлноÑо оÑваÑÑне Ñе маÑабиÑа Ñ Ð´Ð°Ð½Ð½Ð¸Ñе, а пÑи ÑабоÑна книга Ð¾Ñ Ð½Ñколко мегабайÑа Ñази Ñазлика доÑÑига нÑколко поÑÑдÑка какÑо пÑи заÑегнаÑиÑе байÑове, Ñака е и пÑи заделенаÑа памеÑ.
Тази ÑикÑиÑана Ñена е ÑвойÑÑвоÑо, около коеÑо Ñи ÑÑÑÑва да Ñе пÑоекÑиÑа. ÐÑ
одÑÑ ÑилÑÑÑ, изгÑаден вÑÑÑ
Ñ GetSheetNames, Ñе дÑÑжи по един и ÑÑÑ Ð½Ð°Ñин пÑи Ñайл Ñ 200 Ñеда и ÑакÑв Ñ ÑÐ°Ð·Ð¼ÐµÑ 200 MB, Ñака Ñе най-бавниÑÑ Ñайл в пакеÑа веÑе не опÑÐµÐ´ÐµÐ»Ñ ÑемпоÑо пÑи ÑеÑаванеÑо дали даден Ñайл изобÑо Ñи ÑÑÑÑва да бÑде обÑабоÑен.
Ðдно извикване за .xls, .xlsx, и ÑаблониÑе
ÐÑв ÑаÑадаÑа XLS, TXLSWorkbook.GetSheetNames ÑеÑе повеÑе Ð¾Ñ .xls. Ð¢Ñ ÑÑÑо Ñака пÑиема базиÑаниÑе на zip ÑоÑмаÑи .xlsx, .xlsm, .xltx и .xltm, каÑо извлиÑа Ñамо workbook.xml Ð¾Ñ Ð°ÑÑ
ива. Ðа иÑÑинÑки .xls вÑ
од ÑÑ ÑканиÑа BoundSheet запиÑиÑе и ÑпиÑа пÑи пÑÑÐ²Ð¸Ñ EOF Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° Ð³Ð»Ð¾Ð±Ð°Ð»Ð½Ð¸Ñ Ð¿Ð¾Ð´Ð¿Ð¾Ñок, Ñака Ñе големиÑÑ Ð´Ð²Ð¾Ð¸Ñен Ñайл вÑе оÑе ÑÑÑÑва Ñамо килобайÑиÑе за ÑвоеÑо оÑваÑÑне. ФаÑадаÑа XLSX ноÑи гаÑанÑиÑ, коÑÑо има по-голÑмо знаÑение за дÑлгоÑÑоÑно ÑабоÑÐµÑ ÑеÑвизен код, оÑколкоÑо изглежда на пÑÑв поглед: TXLSXWorkbook.GetSheetNames оÑÑÐ°Ð²Ñ Ð¸Ð½ÑÑанÑиÑÑа на ÑабоÑнаÑа книга ниÑо нÑлиÑана, ниÑо попÑлнена, Ñака Ñе инÑÑанÑиÑ, коÑÑо веÑе дÑÑжи оÑвоÑен докÑменÑ, може да ÑондиÑа дÑÑги Ñайлове, без да пÑеÑи на наÑÑоÑÑиÑ. GetODSSheetNames пÑилага ÑÑÑÐ¸Ñ Ð¿Ð¾Ð´Ñ
од кÑм пакеÑиÑе на OpenDocument, каÑо вÑÑко Ð¾Ñ Ñези Ð¸Ð·Ð²Ð¸ÐºÐ²Ð°Ð½Ð¸Ñ Ð¸Ð¼Ð° поÑоÑни пÑеÑоваÑваниÑ, коиÑо ви позволÑÐ²Ð°Ñ Ð´Ð° инÑпекÑиÑаÑе каÑен Ñайл, койÑо никога не Ñе запиÑва на диÑка.
var
Book: TXLSXWorkbook;
Names: TStringList;
I: Integer;
begin
Names := TStringList.Create;
Book := TXLSXWorkbook.Create;
try
if Book.GetSheetNames('upload-7f3a.xlsx', Names) <= 0 then
raise Exception.Create('unreadable workbook package');
if Names.IndexOf('Mapping') < 0 then
raise Exception.Create('required Mapping sheet is missing');
for I := 0 to Names.Count - 1 do
Writeln(Format('sheet %d: %s', [I, Names[I]]));
finally
Book.Free;
Names.Free;
end;
end;
СÑÑоÑо извикване е Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑо за добÑÑ Ð´Ð¸Ð°Ð»Ð¾Ð³Ð¾Ð² пÑозоÑÐµÑ Ð·Ð° импоÑÑиÑане на деÑкÑоп. ÐзбÑойÑе лиÑÑовеÑе, оÑÑавеÑе поÑÑебиÑÐµÐ»Ñ Ð´Ð° избеÑе един и плаÑеÑе за пÑлноÑо оÑваÑÑне едва Ñлед каÑо избоÑÑÑ Ðµ напÑавен. ÐÑи ÑабоÑна книга Ñ Ð¿ÐµÑдеÑÐµÑ Ð»Ð¸ÑÑа ÑазликаÑа е видима: ÑелекÑоÑ, койÑо Ñе поÑвÑва веднага, ÑпÑÑмо ÑакÑв, койÑо блокиÑа, докаÑо ÑелиÑÑ Ñайл Ñе заÑежда на заден план.
ФайловеÑе Ñ Ð¼Ð°ÐºÑоÑи .xlsm и ÑаблониÑе Ñе ÑпиÑÐ²Ð°Ñ ÑоÑно каÑо обикновен .xlsx, ÑÑй каÑо каÑалогÑÑ Ñе намиÑа в ÑÑÑÐ¸Ñ workbook.xml незавиÑимо дали в пакеÑа има vbaProject.bin или не. СледоваÑелно, конвейеÑÑÑ Ð·Ð° вÑ
одÑÑи данни може да избÑои лиÑÑовеÑе на книга Ñ Ð¼Ð°ÐºÑоÑи Ñ Ñел маÑÑÑÑÑизиÑане, без никога да докоÑва ÑÑдÑÑжаниеÑо на макÑоÑа и без да пÑави ниÑо, коеÑо би го изпÑлнило, оÑÑавÑйки ÑеÑениеÑо за пÑавилаÑа за макÑоÑи за еÑапа, койÑо дейÑÑвиÑелно оÑваÑÑ Ñайла.
ЧеÑене на вÑÑнаÑаÑа ÑÑойноÑÑ Ð±ÐµÐ· ÑамозаблÑда
ÐонвенÑииÑе за вÑÑÑане не Ñа еднакви в HotXLS. ÐÑкои Ð¸Ð·Ð²Ð¸ÐºÐ²Ð°Ð½Ð¸Ñ Ð²ÑÑÑÐ°Ñ 1 пÑи ÑÑÐ¿ÐµÑ , дÑÑги вÑÑÑÐ°Ñ Ð±Ñой, Ñака Ñе за ÑÑнкÑииÑе за избÑоÑване единÑÑвенаÑа надеждна пÑовеÑка е да ÑÑеÑиÑаÑе вÑÑка ÑÑойноÑÑ, Ñавна на или по-малка Ð¾Ñ Ð½Ñла, каÑо гÑеÑка, пÑи коеÑо ÑпиÑÑкÑÑ Ñ Ð½Ð¸Ð·Ð¾Ð²Ðµ Ñе изÑиÑÑва. УÑÑоÑвайÑе на изкÑÑениеÑо да пÑоÑеÑеÑе пÑазен ÑпиÑÑк каÑо "ÑабоÑна книга без лиÑÑове". ÐакÑо ECMA-376, Ñака и ÑпеÑиÑикаÑиÑÑа BIFF8 изиÑÐºÐ²Ð°Ñ Ð¿Ð¾Ð½Ðµ един лиÑÑ Ð² валидна ÑабоÑна книга, Ñака Ñе нÑла имена винаги ознаÑава, Ñе ÑеÑенеÑо Ñе е пÑовалило, а не Ñе ÑайлÑÑ Ðµ пÑазен по легиÑимен наÑин.
ÐеÑÑпеÑноÑо избÑоÑване Ñамо по Ñебе Ñи е Ñигнал, койÑо Ñи ÑÑÑÑва да Ñе анализиÑа. Файл .xlsx, пÑи койÑо извикванеÑо Ñе пÑовалÑ, е едно Ð¾Ñ Ð½Ñколко ÑпеÑиÑиÑни неÑа: оÑÑÑзан (truncated), изобÑо не е OOXML Ð¿Ð°ÐºÐµÑ (погÑеÑно еÑикеÑиÑани CSV екÑпоÑÑи Ð¾Ñ Ð´ÑÑги ÑиÑÑеми Ñе поÑвÑÐ²Ð°Ñ ÑÑк поÑÑоÑнно) или е кÑипÑиÑан конÑейнеÑ. РазлиÑаванеÑо им е задаÑа на ÑледваÑаÑа пÑовеÑка. ÐапиÑванеÑо на пÑÑвиÑе байÑове на оÑÑ Ð²ÑÑÐ»ÐµÐ½Ð¸Ñ Ñайл в лога заедно Ñ Ð³ÑеÑкаÑа обикновено пÑевÑÑÑа ÑемаÑа за поддÑÑжка в едно-единÑÑвено ÑÑобÑение.
ÐÑкÑиване на кÑипÑиÑани конÑейнеÑи пÑеди маÑÑÑÑÑизиÑане
ÐÑипÑиÑаниÑÑ .xlsx не е zip. Той е OLE ÑÑÑÑавен Ñайл (OLE compound file), Ð¾Ð±Ð²Ð¸Ð²Ð°Ñ Ð¿Ð¾ÑоÑиÑе EncryptionInfo и EncryptedPackage, Ñака Ñе GetSheetNames не може да види в него и вÑÑÑа гÑеÑка, какÑо вÑеки дÑÑг неÑеÑим Ñайл. CanReadEncrypted ÑеÑÑва за Ñази ÑоÑма на конÑейнеÑа, коеÑо позволÑва на вÑ
одÑÑÐ¸Ñ Ð¿ÑоÑÐµÑ Ð´Ð° маÑÑÑÑÑизиÑа кÑипÑиÑан Ñайл ÑеленаÑоÑено, вмеÑÑо да пÑеглÑÑа обÑа гÑеÑка за ÑеÑене Ð¾Ñ Ð´ÑлбиниÑе на нÑкой ÑабоÑен пÑоÑеÑ:
type
TIntakeRoute = (irNormal, irNeedsPassword, irUnreadable);
function ClassifyUpload(const FileName: string; Names: TStrings): TIntakeRoute;
var
Book: TXLSXWorkbook;
begin
Book := TXLSXWorkbook.Create;
try
// Encrypted OOXML is an OLE container, not a zip: check first,
// because the listing calls cannot look inside it.
if Book.CanReadEncrypted(FileName) then
Exit(irNeedsPassword);
if SameText(ExtractFileExt(FileName), '.ods') then
begin
if Book.GetODSSheetNames(FileName, Names) <= 0 then
Exit(irUnreadable);
end
else if Book.GetSheetNames(FileName, Names) <= 0 then
Exit(irUnreadable);
Result := irNormal;
finally
Book.Free;
end;
end;
ÐÑипÑиÑанеÑо е облаÑÑ, в коÑÑо HotXLS е ÑмиÑлено аÑимеÑÑиÑна, Ñака Ñе маÑÑÑÑÑизиÑанеÑо ÑÑÑбва да Ñе ÑÑобÑази Ñ Ñова. ÐÑÑаÑÑлоÑо .xls кÑипÑиÑане (RC4, RC4 CryptoAPI, XOR) е ÑеÑимо: TXLSWorkbook.Open(FileName, Password) декÑипÑиÑа Ñ Ð¿Ð¾Ð´Ð°Ð´ÐµÐ½Ð° паÑола, и Ñези Ñайлове Ð¼Ð¾Ð³Ð°Ñ Ð´Ð° оÑÑÐ°Ð½Ð°Ñ Ð¿Ð¾ авÑомаÑизиÑÐ°Ð½Ð¸Ñ Ð¿ÑÑ. ÐÑипÑиÑаниÑе пакеÑи OOXML вÑÑвÑÑ Ð² дÑÑгаÑа поÑока. HotXLS може да запиÑе ÑакÑв ÑÑез SaveAsEncrypted, но не може да го пÑоÑеÑе обÑаÑно. OpenEncrypted повдига EXlsxEncryptionNotImplemented пÑи подаване на кÑипÑиÑан пакеÑ, поÑади коеÑо ÑеÑÑниÑÑ Ð´Ð¸Ð·Ð°Ð¹Ð½ на вÑ
одÑÑÐ¸Ñ Ð¿ÑоÑÐµÑ Ð¸Ð·Ð¿ÑаÑа кÑипÑиÑани .xlsx на Ñовек Ñ Excel и запазва поддÑÑжаÑÐ¸Ñ Ð¿Ð°Ñоли .xls в кода.
ÐÑи пакеÑна ÑабоÑа Ñози клаÑиÑикаÑÐ¾Ñ Ð½Ð°Ð¼Ð¸Ñа мÑÑÑоÑо Ñи, каÑо пÑеглежда ÑÑла Ð²Ñ Ð¾Ð´ÑÑÑ Ð´Ð¸ÑекÑоÑиÑ, пÑеди да запоÑне ÑеалнаÑа обÑабоÑка, ÑÑй каÑо вÑÑка пÑовеÑка ÑÑÑÑва пÑиблизиÑелно едно оÑваÑÑне на Ñайл и нÑколко килобайÑа ÑеÑене. ÐÑедваÑиÑелноÑо Ð¼Ñ Ð¿ÑÑкане пÑÐ¾Ð¼ÐµÐ½Ñ Ð½Ð°Ñина на оÑказ, койÑо наиÑÑина инÑеÑеÑÑва поддÑÑжкаÑа. ÐмеÑÑо задаÑа в 3 ÑаÑа ÑÑÑÑинÑа да ÑмÑе на Ñайл 412 Ð¾Ñ 600, полÑÑаваÑе 412 Ñайла на опаÑка и 5 оÑÑ Ð²ÑÑлени на Ð²Ñ Ð¾Ð´Ð° Ñ Ð¿ÑикаÑена пÑиÑина за вÑеки. СÑÑиÑе Ð¸Ð·Ð²Ð¸ÐºÐ²Ð°Ð½Ð¸Ñ Ð½Ð° библиоÑекаÑа, но много по-добÑа опеÑаÑивна иÑÑоÑиÑ.
ÐÑпÑоÑиÑе, на коиÑо извикванеÑо за избÑоÑване не може да оÑговоÑи
ÐменаÑа и ÑедÑÑ Ñа вÑиÑко, коеÑо полÑÑаваÑе. ÐзвикваниÑÑа за избÑоÑване не ÐºÐ°Ð·Ð²Ð°Ñ Ð½Ð¸Ñо за видимоÑÑÑа, Ñака Ñе ÑкÑиÑиÑе (hidden) и много ÑкÑиÑиÑе (very-hidden) лиÑÑове Ñе поÑвÑÐ²Ð°Ñ Ð² ÑпиÑÑка каÑо вÑеки дÑÑг. Те не ÑÑобÑÐ°Ð²Ð°Ñ ÑазмеÑи на Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ð¸Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½, бÑой клеÑки или ÑвойÑÑва на докÑменÑа. ЧаÑÑÑа docProps/core.xml ÑÑÑо е малка, но Ð´Ð½ÐµÑ Ð½Ñма Ñонда Ñамо за ÑвойÑÑва, Ñака Ñе меÑаданниÑе за авÑÐ¾Ñ Ð¸ заглавие вÑе оÑе ÑÑÑÑÐ²Ð°Ñ Ð¿Ñлно Open. ЧиÑÑиÑÑ Ð½Ð°Ñин да Ñе живее Ñ Ñова е да Ñе оÑÑавÑÑ ÐµÐ²ÑиниÑе ÑакÑи да маÑÑÑÑÑизиÑÐ°Ñ Ð²Ñеки Ñайл и да Ñе запазÑÑ ÑкÑпиÑе за ÑайловеÑе, коиÑо пÑÐµÐ¼Ð¸Ð½Ð°Ð²Ð°Ñ ÑÑпеÑно маÑÑÑÑÑизиÑанеÑо. Ðа ÑайловеÑе, коиÑо пÑодÑÐ»Ð¶Ð°Ð²Ð°Ñ ÐºÑм ÑÑлоÑÑно ÑеÑене, ÑканиÑанеÑо Ñамо за ÑеÑене на голÑм .xls ÑабоÑи забележимо по-бÑÑзо Ñ _DisableGraphics := True, коеÑо пÑопÑÑка паÑÑванеÑо на OfficeArt. Само никога не запиÑвайÑе Ð¾Ñ Ñази инÑÑанÑиÑ: пÑеÑкоÑениÑÑ Ð³ÑаÑиÑен Ñлой е изÑезнал Ð¾Ñ Ð¼Ð¾Ð´ÐµÐ»Ð° и запиÑванеÑо би го пÑемаÑ
нало Ð¾Ñ Ñайла.
ФайловеÑе, коиÑо пÑÐµÐ¼Ð¸Ð½Ð°Ð²Ð°Ñ ÑÑиажа, обикновено оÑÐ¸Ð²Ð°Ñ ÐºÑм по-дÑлбок анализ. РабоÑен Ð¿Ð»Ð¾Ñ Ð·Ð° Ð¾Ð´Ð¸Ñ Ð¸ пÑеобÑазÑване на ÑабоÑни книги Ð¾Ð±Ñ Ð²Ð°Ñа бÑоÑÑиÑе за вÑеки лиÑÑ, коиÑо Ñи ÑÑÑÑва да Ñе ÑÑбиÑÐ°Ñ Ñлед обоÑновка на пÑлно оÑваÑÑне, а ÑÑководÑÑвоÑо за пÑоизводиÑелноÑÑ Ð½Ð° големи ÑабоÑни книги Ð¾Ð±Ñ Ð²Ð°Ñа Ñова как Ñова пÑлно оÑваÑÑне да оÑÑане бÑÑзо.
HotXLS е оÑигинална Object Pascal библиоÑека за елекÑÑонни ÑаблиÑи за Delphi и C++Builder; ÑÑлаÑа повÑÑÑ Ð½Ð¾ÑÑ Ð½Ð° API, вклÑÑиÑелно показаниÑе ÑÑк Ð¸Ð·Ð²Ð¸ÐºÐ²Ð°Ð½Ð¸Ñ Ð·Ð° инÑпекÑиÑ, е докÑменÑиÑана на ÑÑÑаниÑаÑа на пÑодÑкÑа HotXLS Component.