问题描述
procedure ExcelToPDF(const InputFileName,OutputFileName: string);
var
Excel: Variant;
Workbook: Variant;
begin
try
CoInitializeEx(nil,0);
//Открытие Excel
Excel := CreateOleObject('Excel.Application');
// Excel.Application.EnableEvents := False;
Excel.Application.displayAlerts := False;
Excel.Visible := False;
if not VarIsNull(Excel) then
begin
//Открытие файла
Workbook := Excel.Workbooks.Open(InputFileName);
//Сохранение в PDF
Workbook.ExportAsFixedFormat(xlTypePDF,OutputFileName);
Writeln('OK');
end
else
begin
raise Exception.Create('Не удалось открыть Excel');
end;
finally
if not VarIsNull(Excel) then
begin
Excel.Quit;
Excel := 0;
end;
end;
end;
它工作正常,但是对于某些工作簿,当程序尝试打开工作簿时(还有屏幕截图),会出现一个错误输入对话框:
名称冲突
名称不能与内置名称相同。
旧名称:Print_Area
新名称:
确定取消
旧名称可以是Print_Area或_FilterDatabase或其他名称。这是非常常见的错误,但我没有找到真正的解决方案。但是关键问题在这里:当我自己在Excel中打开问题工作簿时,它在没有任何对话框的情况下工作正常,仅当我在OLE中用程序打开它时,它才会出现。如果在OLE中我们仅使用Excel怎么办?因此,也许Excel使用其他参数打开文件?我正在尝试使用Open方法参数,但是什么也没有。
解决方法
感谢您的所有评论。我找到了解决方案。在VBA中,有GetObject函数。我在Internet Delphi实现中找到了它。在那里:
function GetObject(const AFileName: TFileName): IDispatch;
var
vDispatch : IDispatch;
vBindCtx : IBindCtx;
vMoniker : IMoniker;
vChEaten : Integer;
begin
Result := nil;
vDispatch := nil;
vBindCtx := nil;
if CreateBindCtx(0,vBindCtx) = S_OK then
begin
vMoniker := nil;
if MkParseDisplayName(vBindCtx,PWideChar(WideString(AFileName)),vChEaten,vMoniker) = S_OK then
begin
if vMoniker.BindToObject(vBindCtx,nil,IDispatch,vDispatch) = S_OK then
Result := vDispatch;
end;
end;
end;
因此,而不是这两行:
Excel := CreateOleObject('Excel.Application');
Workbook := Excel.Workbooks.Open(InputFileName);
仅使用一个:
Workbook := GetObject(InputFileName);