home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 October / Chip_2002-10_cd1.bin / zkuste / delphi / kolekce / d56 / FLEXCEL.ZIP / XLSAdapter / XLSAdapter.pas < prev    next >
Pascal/Delphi Source File  |  2002-07-02  |  15KB  |  493 lines

  1. unit XLSAdapter;
  2.  
  3. //Note: Excel uses 1-Based arrays, and that's the interface we present to our users.
  4. // but, TExcelWorkbook uses 0-Based arrays, to be consistent with the file format (made in C)
  5. //So here we have to add and substract 1 everywere to be consistent.
  6.  
  7. interface
  8.  
  9. uses
  10.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  11.   UExcelAdapter, TemplateStore, UFlxMessages, UExcelRecords, XlsMessages,
  12.   ActiveX, ComObj, UXlsOLEDoc, AXCtrls, UFlxRowComments,
  13.   {$IFDEF ConditionalExpressions}{$if CompilerVersion >= 14} variants,{$IFEND}{$ENDIF} //Delphi 6 or above
  14.   UXlsSheet;
  15.  
  16. type
  17.   TXLSAdapter = class(TExcelAdapter)
  18.   private
  19.     FTemplateStore: TXlsTemplateStore;
  20.     procedure SetTemplateStore(const Value: TXLSTemplateStore);
  21.     { Private declarations }
  22.   protected
  23.     { Protected declarations }
  24.   public
  25.     constructor Create(AOwner:TComponent);override;
  26.     function GetWorkbook: TExcelFile;override;
  27.     { Public declarations }
  28.   published
  29.     property TemplateStore: TXLSTemplateStore read FTemplateStore write SetTemplateStore;
  30.     { Published declarations }
  31.   end;
  32.  
  33.   TXLSFile = class(TExcelFile)
  34.   private
  35.     FAdapter: TXLSAdapter;
  36.     FActiveSheet: integer;
  37.  
  38.     FWorkbook: TWorkbook;
  39.     FTemplate: TXlsStorageList;
  40.     FTmpTemplate: TXlsStorageList;
  41.  
  42.     FirstColumn,LastColumn: integer;
  43.  
  44.     RowPictures: TRowComments;
  45.     procedure ParsePictures;
  46.  
  47.   protected
  48.     function GetActiveSheet: byte; override;
  49.     procedure SetActiveSheet(const Value: byte); override;
  50.     function GetActiveSheetName: WideString; override;
  51.     procedure SetActiveSheetName(const Value: WideString); override;
  52.   public
  53.     constructor Create(const aAdapter: TXLSAdapter );
  54.     destructor Destroy; override;
  55.  
  56.     procedure Connect;override;
  57.     procedure Disconnect;override;
  58.  
  59.     procedure OpenFile(const FileName: TFileName);override;
  60.     procedure CloseFile; override;
  61.  
  62.     procedure InsertAndCopySheets (const CopyFrom, InsertBefore, SheetCount: byte);override;
  63.     function SheetCount: byte;override;
  64.     procedure SelectSheet(const SheetNo:integer); override;
  65.  
  66.     procedure DeleteMarkedRows(const Mark: widestring);override;
  67.     procedure RefreshPivotTables;override;
  68.  
  69.     procedure Save(const AutoClose: boolean; const FileName: string; const OnGetFileName: TOnGetFileNameEvent);override;
  70.  
  71.     procedure InsertAndCopyRows(const FirstRow, LastRow, DestRow, aCount: integer; const OnlyFormulas: boolean);override;
  72.     procedure DeleteRows(const aRow, aCount: word);override;
  73.  
  74.     procedure BeginSheet;override;
  75.     procedure EndSheet(const RowOffset: integer);override;
  76.  
  77.     function CanOptimizeRead: boolean; override;
  78.  
  79.  
  80.     function GetCommentsCount(Row: integer): integer; override;
  81.     function GetCommentText(Row, aPos: integer): widestring; override;
  82.     function GetPictureName(Row, aPos: integer): widestring;  override;
  83.     function GetPicturesCount(Row: integer): integer;  override;
  84.  
  85.     function GetExcelNameCount: integer;  override;
  86.     function GetRangeName(index: integer): widestring;  override;
  87.     function GetRangeR1(index: integer): integer; override;
  88.     function GetRangeR2(index: integer): integer; override;
  89.     function GetRangeC1(index: integer): integer; override;
  90.     function GetRangeC2(index: integer): integer; override;
  91.     function GetRangeSheet(index: integer): integer; override;
  92.     procedure AssignPicture(const Row, aPos: integer; const Pic: string; const PicType: TXlsImgTypes); override;
  93.     procedure AssignComment(const Row, aPos: integer; const Comment: widestring); override;
  94.  
  95.     function CellCount(const aRow: integer): integer;override;
  96.     function GetCellData(const aRow, aColOffset: integer): variant;override;
  97.     function GetCellDataX(const aRow, aColOffset: integer): TXlsCellValue;override;
  98.     procedure AssignCellData(const aRow, aColOffset: integer; const Value: variant);override;
  99.     procedure AssignCellDataX(const aRow, aColOffset: integer; const Value: TXlsCellValue);override;
  100.     function MaxRow: integer; override;
  101.     function IsEmptyRow(const aRow: integer): boolean; override;
  102.     function GetCellValue(aRow, aCol: integer): Variant; override;
  103.     procedure SetCellValue(aRow, aCol: integer; const Value: Variant); override;
  104.  
  105.     procedure SetBounds(const aRangePos: integer);override;
  106.  
  107.     procedure PrepareBlockData(const R1,C1,R2,C2: integer);override;
  108.     procedure AssignBlockData(const Row,Col: integer; const v: variant);override;
  109.     procedure PasteBlockData;override;
  110.   end;
  111.  
  112.  
  113. procedure Register;
  114.  
  115. implementation
  116. {$R IXLSAdapter.res}
  117. procedure Register;
  118. begin
  119.   RegisterComponents('FlexCel', [TXLSAdapter]);
  120. end;
  121.  
  122. { TXLSAdapter }
  123.  
  124. constructor TXLSAdapter.Create(AOwner: TComponent);
  125. begin
  126.   inherited;
  127. end;
  128.  
  129. function TXLSAdapter.GetWorkbook: TExcelFile;
  130. begin
  131.   Result:= TXLSFile.Create(Self);
  132. end;
  133.  
  134. procedure TXLSAdapter.SetTemplateStore(const Value: TXLSTemplateStore);
  135. begin
  136.   FTemplateStore := Value;
  137. end;
  138.  
  139. { TXLSFile }
  140.  
  141. procedure TXLSFile.AssignCellData(const aRow, aColOffset: integer; const Value: variant);
  142. var
  143.   V: TXlsCellValue;
  144. begin
  145.   if not FWorkbook.IsWorkSheet(FActiveSheet-1) then exit;
  146.   if aRow-1<FWorkbook.WorkSheets[FActiveSheet-1].Cells.CellList.Count then
  147.   begin
  148.     V.Value:=Value; V.XF:=-1;
  149.     FWorkbook.WorkSheets[FActiveSheet-1].Cells.CellList.Value[aRow-1, FirstColumn + aColOffset]:=V;
  150.   end;
  151. end;
  152.  
  153. procedure TXLSFile.AssignCellDataX(const aRow, aColOffset: integer; const Value: TXlsCellValue);
  154. begin
  155.   if not FWorkbook.IsWorkSheet(FActiveSheet-1) then exit;
  156.   if aRow-1<FWorkbook.WorkSheets[FActiveSheet-1].Cells.CellList.Count then
  157.     FWorkbook.WorkSheets[FActiveSheet-1].Cells.CellList.Value[aRow-1, FirstColumn + aColOffset]:=Value;
  158. end;
  159.  
  160. procedure TXLSFile.AssignComment(const Row, aPos: integer;
  161.   const Comment: widestring);
  162. begin
  163.   if FWorkbook.IsWorkSheet(ActiveSheet-1) then
  164.   begin
  165.     if Comment='' then FWorkbook.WorkSheets[ActiveSheet-1].Notes[Row-1].Delete(aPos) else
  166.     FWorkbook.WorkSheets[ActiveSheet-1].Notes[Row-1][aPos].Text:= Comment;
  167.   end;
  168. end;
  169.  
  170. procedure TXLSFile.AssignPicture(const Row, aPos: integer; const Pic: string; const PicType: TXlsImgTypes);
  171. begin
  172.   if FWorkbook.IsWorkSheet(ActiveSheet-1) then
  173.     FWorkbook.WorkSheets[ActiveSheet-1].AssignDrawing(RowPictures[Row][aPos], Pic, PicType);
  174. end;
  175.  
  176. procedure TXLSFile.ParsePictures;
  177. var
  178.   i:integer;
  179.  
  180. begin
  181.   FreeAndNil(RowPictures);
  182.   RowPictures:= TRowComments.Create;
  183.   if FWorkbook.IsWorkSheet(ActiveSheet-1) then
  184.     for i:=0 to FWorkbook.WorkSheets[ActiveSheet-1].DrawingCount-1 do
  185.       RowPictures.Add(FWorkbook.WorkSheets[ActiveSheet-1].DrawingRow[i]+1, i);
  186. end;
  187.  
  188.  
  189. procedure TXLSFile.BeginSheet;
  190. begin
  191.   ParsePictures;
  192. end;
  193.  
  194. function TXLSFile.CellCount(const aRow: integer): integer;
  195. begin
  196.   if not FWorkbook.IsWorkSheet(FActiveSheet-1) then begin; Result:=0; exit; end;
  197.   if aRow-1<FWorkbook.WorkSheets[FActiveSheet-1].Cells.CellList.Count then
  198.     Result:=LastColumn-FirstColumn+1
  199.   else Result:=0;
  200. end;
  201.  
  202. procedure TXLSFile.CloseFile;
  203. begin
  204.   //Nothing
  205. end;
  206.  
  207. procedure TXLSFile.Connect;
  208. begin
  209.   FWorkbook:= TWorkbook.Create;
  210. end;
  211.  
  212. constructor TXLSFile.Create(const aAdapter: TXLSAdapter);
  213. begin
  214.   inherited Create;
  215.   FAdapter:= aAdapter;
  216. end;
  217.  
  218. procedure TXLSFile.DeleteMarkedRows(const Mark: widestring);
  219. var
  220.   i:integer;
  221.   s: widestring;
  222. begin
  223.   if not FWorkbook.IsWorkSheet(FActiveSheet-1) then exit;
  224.   for i:=FWorkbook.WorkSheets[FActiveSheet-1].Cells.CellList.Count -1 downto 0 do
  225.   try
  226.     s:= FWorkbook.WorkSheets[FActiveSheet-1].Cells.CellList.Value[i,0].Value;
  227.     if (s=Mark) then
  228.       FWorkbook.DeleteRows(FActiveSheet-1, i, 1);
  229.   except
  230.     //nothing
  231.   end;//except
  232. end;
  233.  
  234. procedure TXLSFile.DeleteRows(const aRow, aCount: word);
  235. begin
  236.   FWorkbook.DeleteRows(FActiveSheet-1, aRow-1, aCount);
  237. end;
  238.  
  239. destructor TXLSFile.Destroy;
  240. begin
  241.   FreeAndNil(RowPictures);
  242.   FreeAndNil(FTmpTemplate);
  243.   inherited;
  244. end;
  245.  
  246. procedure TXLSFile.Disconnect;
  247. begin
  248.   FreeAndNil(FWorkbook);
  249. end;
  250.  
  251. procedure TXLSFile.EndSheet(const RowOffset: integer);
  252. begin
  253.   //Nothing
  254. end;
  255.  
  256. function TXLSFile.GetActiveSheet: byte;
  257. begin
  258.   Result:= FActiveSheet;
  259. end;
  260.  
  261. function TXLSFile.GetActiveSheetName: WideString;
  262. begin
  263.   Result:= FWorkbook.Globals.SheetName[FActiveSheet-1];
  264. end;
  265.  
  266. function TXLSFile.GetCellData(const aRow, aColOffset: integer): variant;
  267. begin
  268.   if not FWorkbook.IsWorkSheet(FActiveSheet-1) then begin; Result:=unassigned; exit; end;
  269.   Result:=FWorkbook.WorkSheets[FActiveSheet-1].Cells.CellList.Value[aRow-1,FirstColumn+aColOffset].Value;
  270. end;
  271.  
  272. function TXLSFile.GetCellDataX(const aRow, aColOffset: integer): TXlsCellValue;
  273. begin
  274.   if not FWorkbook.IsWorkSheet(FActiveSheet-1) then begin; Result.Value:=unassigned; Result.XF:=-1; exit; end;
  275.   Result:=FWorkbook.WorkSheets[FActiveSheet-1].Cells.CellList.Value[aRow-1,FirstColumn+aColOffset];
  276. end;
  277.  
  278. function TXLSFile.GetCommentsCount(Row: integer): integer;
  279. begin
  280.   if FWorkbook.IsWorkSheet(ActiveSheet-1) then
  281.     if Row-1<FWorkbook.WorkSheets[ActiveSheet-1].Notes.Count then
  282.       Result:=FWorkbook.WorkSheets[ActiveSheet-1].Notes[Row-1].Count
  283.     else
  284.       Result:=0
  285.   else
  286.     Result:=0;
  287. end;
  288.  
  289. function TXLSFile.GetCommentText(Row, aPos: integer): widestring;
  290. begin
  291.   if FWorkbook.IsWorkSheet(ActiveSheet-1) then
  292.     Result:=FWorkbook.WorkSheets[ActiveSheet-1].Notes[Row-1][aPos].Text
  293.   else
  294.     Result:='';
  295. end;
  296.  
  297. function TXLSFile.GetExcelNameCount: integer;
  298. begin
  299.   Result:=FWorkbook.Globals.Names.Count;
  300. end;
  301.  
  302. function TXLSFile.GetPictureName(Row, aPos: integer): widestring;
  303. begin
  304.   Result:= '';
  305.   if not FWorkbook.IsWorksheet(FActiveSheet-1) then exit;
  306.   Result:=FWorkbook.WorkSheets[FActiveSheet-1].DrawingName[RowPictures[Row][aPos]];
  307. end;
  308.  
  309. function TXLSFile.GetPicturesCount(Row: integer): integer;
  310. begin
  311.   Result:=RowPictures[Row].Count;
  312. end;
  313.  
  314. function TXLSFile.GetRangeName(index: integer): widestring;
  315. begin
  316.   Result:= FWorkbook.Globals.Names[index-1].Name;
  317. end;
  318.  
  319. function TXLSFile.GetRangeR1(index: integer): integer;
  320. begin
  321.   Result:= FWorkbook.Globals.Names[index-1].R1+1;
  322. end;
  323.  
  324. function TXLSFile.GetRangeR2(index: integer): integer;
  325. begin
  326.   Result:= FWorkbook.Globals.Names[index-1].R2+1;
  327. end;
  328.  
  329. function TXLSFile.GetRangeC1(index: integer): integer;
  330. begin
  331.   Result:= FWorkbook.Globals.Names[index-1].C1+1;
  332. end;
  333.  
  334. function TXLSFile.GetRangeC2(index: integer): integer;
  335. begin
  336.   Result:= FWorkbook.Globals.Names[index-1].C2+1;
  337. end;
  338.  
  339. function TXLSFile.GetRangeSheet(index: integer): integer;
  340. begin
  341.   Result:= FWorkbook.Globals.Names[index-1].RefersToSheet(FWorkbook.Globals.References.GetSheet)+1;
  342. end;
  343.  
  344. procedure TXLSFile.InsertAndCopyRows(const FirstRow, LastRow, DestRow,
  345.   aCount: integer; const OnlyFormulas: boolean);
  346. begin
  347.   FWorkbook.InsertAndCopyRows(FActiveSheet-1, FirstRow-1, LastRow-1, DestRow-1, aCount, OnlyFormulas)
  348. end;
  349.  
  350. procedure TXLSFile.InsertAndCopySheets(const CopyFrom, InsertBefore,
  351.   SheetCount: byte);
  352. begin
  353.   FWorkbook.InsertSheets(CopyFrom-1, InsertBefore-1, SheetCount);
  354. end;
  355.  
  356. procedure TXLSFile.OpenFile(const FileName: TFileName);
  357. var
  358.   WorkbookStr: widestring;
  359. begin
  360.   WorkbookStr:=WorkbookStrS;
  361.   FTemplate:=nil;
  362.   FreeAndNil(FTmpTemplate);
  363.  
  364.   if FAdapter.TemplateStore<>nil then
  365.     FTemplate:=FAdapter.TemplateStore.Storages[FileName]
  366.   else
  367.   begin
  368.     FTmpTemplate:=TXlsStorageList.Create;
  369.     FTmpTemplate.LoadFrom(SearchPathStr(FileName));
  370.     FTemplate:=FTmpTemplate;
  371.   end;
  372.  
  373.   FWorkbook.LoadFromStream(FTemplate.Stream[WorkbookStr]);
  374.   FActiveSheet:=FWorkbook.ActiveSheet+1;
  375. end;
  376.  
  377.  
  378. procedure TXLSFile.RefreshPivotTables;
  379. begin
  380.   //Nothing
  381. end;
  382.  
  383.  
  384.  
  385. procedure TXLSFile.Save(const AutoClose: boolean; const FileName: string;
  386.   const OnGetFileName: TOnGetFileNameEvent);
  387. var
  388.   aFileName: TFileName;
  389.   OutputFileName: WideString;
  390.   WorkbookStr: widestring;
  391.  
  392.   i:integer;
  393.   DocOUT: IStorage;
  394.   StreamOUT: IStream;
  395.   DataStream: TOleStream;
  396. begin
  397.   WorkbookStr:=WorkbookStrS;
  398.   aFileName:=Filename;
  399.   if Assigned (OnGetFileName) then OnGetFileName(Self,0,aFilename);
  400.   OutputFileName:= aFileName;
  401.  
  402.   if FileExists(FileName) then raise Exception.CreateFmt(ErrCantWriteToFile, [FileName]);  //this is to avoid a criptic ole xxxx error...
  403.  
  404.   //Create output file
  405.   OleCheck(StgCreateDocFile(PWideChar(OutputFileName), OptionsWrite, 0, DocOUT));
  406.   for i:=0 to FTemplate.Count-1 do
  407.     if FTemplate[i].Name<>WorkbookStr then
  408.     begin
  409.       FTemplate[i].SaveToDoc(DocOUT);
  410.     end;
  411.  
  412.   OleCheck(DocOUT.CreateStream(PWideChar(WorkbookStr), OptionsWrite, 0, 0, StreamOUT));
  413.   DataStream:=TOleStream.Create(StreamOUT);
  414.   try
  415.     FWorkbook.SaveToStream(DataStream);
  416.   finally
  417.     FreeAndNil(DataStream);
  418.   end; //Finally
  419. end;
  420.  
  421. procedure TXLSFile.SelectSheet(const SheetNo:integer);
  422. begin
  423.   FWorkbook.ActiveSheet:=SheetNo-1;
  424. end;
  425.  
  426. procedure TXLSFile.SetActiveSheet(const Value: byte);
  427. begin
  428.   FActiveSheet:=Value;
  429. end;
  430.  
  431. procedure TXLSFile.SetActiveSheetName(const Value: WideString);
  432. begin
  433.   FWorkbook.Globals.SheetName[FActiveSheet-1]:= Value;
  434. end;
  435.  
  436. procedure TXLSFile.SetBounds(const aRangePos: integer);
  437. begin
  438.   FirstColumn:=FWorkbook.Globals.Names[aRangePos-1].C1;
  439.   LastColumn:=FWorkbook.Globals.Names[aRangePos-1].C2;
  440. end;
  441.  
  442. function TXLSFile.SheetCount: byte;
  443. begin
  444.   Result:=FWorkbook.Globals.SheetCount;
  445. end;
  446.  
  447. procedure TXLSFile.AssignBlockData(const Row, Col: integer; const v: variant);
  448. begin
  449.   AssignCellData(Row, Col, v);
  450. end;
  451.  
  452. procedure TXLSFile.PasteBlockData;
  453. begin
  454.   // Nothing
  455. end;
  456.  
  457. procedure TXLSFile.PrepareBlockData(const R1, C1, R2, C2: integer);
  458. begin
  459.   // Nothing
  460. end;
  461.  
  462. function TXLSFile.MaxRow: integer;
  463. begin
  464.   if not FWorkbook.IsWorkSheet(FActiveSheet-1) then begin; Result:=0;exit;end;
  465.   Result:= FWorkbook.WorkSheets[FActiveSheet-1].Cells.CellList.Count;
  466. end;
  467.  
  468. function TXLSFile.GetCellValue(aRow, aCol: integer): Variant;
  469. begin
  470.   Result:= GetCellData(aRow, aCol-FirstColumn-1);
  471. end;
  472.  
  473. procedure TXLSFile.SetCellValue(aRow, aCol: integer; const Value: Variant);
  474. begin
  475.   AssignCellData(aRow, aCol-FirstColumn-1, Value);
  476. end;
  477.  
  478. function TXLSFile.IsEmptyRow(const aRow: integer): boolean;
  479. begin
  480.   if not FWorkbook.IsWorkSheet(FActiveSheet-1) then begin; Result:=true;exit;end;
  481.   Result:=
  482.     (aRow-1<0) or (aRow-1>= MaxRow) or
  483.     not FWorkbook.WorkSheets[FActiveSheet-1].Cells.RowList.HasRow(aRow-1);
  484. end;
  485.  
  486.  
  487. function TXLSFile.CanOptimizeRead: boolean;
  488. begin
  489.   Result:=true;
  490. end;
  491.  
  492. end.
  493.