delphi - 如何使用 tFDMemTable 将多个数据表保存到一个文件中
问题描述
我将许多 Excel 工作表一一导入到许多 tFDMemTables 中并进行了修改。现在我尝试将它们保存到任何类型的 ONE 文件中,以便进一步使用 tFDMemTable 进行维护,不再使用 Excel。如何将多个 tFDMemTables 制作为一个对象以保存到一个文件,而不是通过 APPEND?
我在 Windows 10 中使用 Delphi 10.3 Community。参考推荐我使用它的 FireDAC。
在 .Net 中,我使用以下简单代码将多表层制作成 ONE DataSet 和 ONE XML 文件。但是在Delphi中,数据表似乎意味着数据集。那么是什么保存了许多数据表,如 .Net DataSet?
DataSet.Tables.Add(Table);
DataSet.WriteXml(FileName);
解决方案
下面的代码显示了如何根据每个 FDMemTable 行一个工作簿将一系列 Excel 文件(工作簿)保存到 FDMemTable 的行中。这是通过将 Excel 文件保存在 FDMemTable 的 blob 字段中来完成的。
GetFiles 方法显示如何扫描文件夹中的 Excel 文件并使用 SaveFile 方法将它们保存到 FDMemTable。FDMemTable 行包括 Excel 文件的名称和找到它的路径。
GetExcelMethod 完成后,它将 FDMemTable 内容保存到一个文件中,然后可以将其复制到其他地方。
WriteFiles 方法从 FDMemTable 中读取 Excel 文件并将它们写入指定目录:该方法还展示了如何使用 Excel 打开文件。
当然,这里展示的技术不仅限于 Excel 文件:通过调整 GetFiles 中的文件掩码,它可以找到并保存任何类型的文件。
uses [...] ShellAPI;
type
TForm1 = class(TForm)
[...]
private
ID : Integer; // used to generate iD field for FDMemTable1
[...]
public
end;
procedure TForm1.GetFiles(Path : String);
// Find all files in a given directory and save them to FDMemTable1
var
SearchRec : TSearchRec;
Res : Integer;
FN : String;
begin
Path := Path + '\*.xl*';
Res := FindFirst(Path, faAnyFile, SearchRec);
if Res = 0 {SearchRec.Attr and faAnyFile = faAnyFile} then begin
repeat
SaveFile(ExtractFilePath(Path) + SearchRec.Name);
Res := FindNext(SearchRec);
until Res <> 0;
FindClose(SearchRec);
FN := ExtractFilePath(Application.ExeName) + 'Excelfiles.XML';
FDMemTable1.SaveToFile(FN, sfXML);
end;
end;
procedure TForm1.SaveFile(FileName : String);
// Save an individual file to FDMemTable1
var
APath,
AName : String;
begin
APath := ExtractFilePath(FileName);
AName := ExtractFileName(FileName);
inc(ID);
FDMemTable1.Insert;
FDMemTable1.FieldByName('ID').AsInteger := ID;
FDMemTable1.FieldByName('FilePath').AsString := APath;
FDMemTable1.FieldByName('FileName').AsString := AName;
TBlobField(FDMemTable1.FieldByName('FileData')).LoadFromFile(FileName);
FDMemTable1.Post;
end;
procedure TForm1.WriteFiles;
// Extract files from FDMemTable1 to s given directory
var
FileName : String;
begin
if not FDMemTable1.Active then
FDMemTable1.Open;
FDMemTable1.First;
while not FDMemTable1.Eof do begin
FileName := FDMemTable1.FieldByName('FileName').AsString;
TBlobField(FDMemTable1.FieldByName('FileData')).SaveToFile('C:\Temp\'+ FileName);
// Uncomment the following line to have the file opened in Excel; you'll need to add ShellAPI to your Uses list
// ShellExecute(Handle, 'Open', PChar('C:\Temp\' + Filename), '','',SW_SHOWNORMAL);
FDMemTable1.Next;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
FieldDef : TFieldDef;
begin
ID := 0;
FieldDef := FDMemTable1.FieldDefs.AddFieldDef;
FieldDef.Name := 'ID';
FieldDef.DataType := ftInteger;
FieldDef := FDMemTable1.FieldDefs.AddFieldDef;
FieldDef.Name := 'FilePath';
FieldDef.DataType := ftString;
FieldDef.Size := Max_Path;
FieldDef := FDMemTable1.FieldDefs.AddFieldDef;
FieldDef.Name := 'FileName';
FieldDef.DataType := ftString;
FieldDef.Size := Max_Path;
FieldDef := FDMemTable1.FieldDefs.AddFieldDef;
FieldDef.Name := 'FileData';
FieldDef.DataType := ftBlob;
FDMemTable1.CreateDataSet;
end;
procedure TForm1.btnSaveClick(Sender: TObject);
begin
GetFiles('D:\aaad7\aaaofficeauto');
end;
procedure TForm1.btnWriteFilesClick(Sender: TObject);
begin
WriteFiles;
end;
推荐阅读
- python - Rock Paper Scissors (Python) - 枚举列表,根据逻辑提取值,并将这些值与原始列表进行比较
- amazon-web-services - 如果项目在 DynamoDB 中不存在,则放入表中
- javascript - 在最近的浏览器中播放 HTML 5 视频是否需要 Javascript?
- reactjs - flex 方向行项目溢出如何解决这个问题?
- sql-server - 找出销量排名前5位的厂商中各型号的平均价格,并按平均价格订购
- javascript - 如何将我的过滤器脚本设置为仅在首次加载时显示网站上默认按钮位置的项目?
- javascript - 容器绑定脚本上的错误“预期的 OAuth 2 访问令牌”
- javascript - 如何正确控制执行流程 Javascript 异常处理
- javascript - 重复字符的 JavaScript 正则表达式规则
- python-3.x - 语法 X = Add() ([tensor1, tensor2]) 在使用 keras.layers.add 构建 ResNET 时如何准确工作?