PHP Conference Japan 2024

COM 函数

参见

有关 COM 的更多信息,请阅读» COM 规范。您可能在我们的PHP 和 COM常见问题解答中找到一些其他有用的信息。如果您考虑在服务器端使用 MS Office 应用程序,则应阅读此处的相关信息:» Office 服务器端自动化的注意事项

目录

添加注释

用户贡献的注释 31 条注释

9
Sorin Negulescu
8 年前
我花了大量时间试图在使用 Apache 作为服务的 Windows 服务器上使 word.application 工作。
如果从命令行(而不是作为服务)启动 Apache,则该应用程序可以工作。

希望这能帮助其他人避免浪费时间尝试解决此问题,以下是我发现的内容

- 在 php.ini 中,确保您在 [COM_DOT_NET] 下有以下键:extension=php_com_dotnet.dll
- Apache 应在普通用户帐户(而不是 SYSTEM 帐户)下运行。运行 services.msc 并在 Apache 服务的“属性”选项卡下填写用户信息。
- 确保您能够在该用户帐户下正常启动 MS Word 并关闭可能出现的任何对话框(许可证、带有首字母缩写的您的信息等)。再次启动 Word 并确保没有对话框出现。
- 启动 dcomcnfg.exe->控制台根目录->组件服务->计算机->我的电脑->DCOM 配置->Microsoft Office Word 97 - 2003->右键单击(属性)->标识选项卡并填写与 Apache 服务相同的用户帐户信息。
- 如果您找不到 Microsoft Office Word 97 - 2003,请确保您正在启动正确的 DCOM 配置(64 位与 32 位),具体取决于您安装的 Office 版本。要启动 32 位版本,请运行:mmc comexp.msc /32

在执行上述步骤之前,winword.exe 应用程序会显示在任务管理器中,但如果您查看内存消耗,您会注意到两件事
- 它会缓慢增加
- 它通常会在大约 7-8 MB 处停止。

关键词:COM、word.application、Apache、服务、winword、超时、无错误
3
tomas dot pacl at atlas dot cz
21 年前
在 PHP 4.3.2(以及 PHP 的未来版本)中通过引用传递参数

在 PHP 4.3.2 中,allow_call_time_pass_reference 选项默认设置为“Off”,并且未来版本可能不再支持此选项。
某些 COM 函数具有按引用传递的参数。必须使用 VARIANT 对象来调用这些函数,但它将在变量名前没有“&”的情况下传递。

示例

<?php
$myStringVariant
= new VARIANT("over-write me", VT_BSTR);

/* 可以工作 */
$result = $comobj->DoSomethingTo($myStringVariant );

/* 仅当 allow_call_time_pass_reference 选项设置为“On”时才有效,并且在 PHP 的未来版本中可能无效 */
$result = $comobj->DoSomethingTo(&$myStringVariant );

/* 可以通过以下方式获取变体中的值: */
$theActualValue = $myStringVariant->value;
?>
4
tomfmason at nospam-gmail dot com
17 年前
要获取 CPU 负载百分比,您可以执行以下操作。

<?php
$wmi
= new COM('winmgmts://');
$processor = $wmi->ExecQuery("SELECT * FROM Win32_Processor");
foreach(
$processor as $obj){
$cpu_load_time = $obj->LoadPercentage;
}
echo
$cpu_load_time;
?>

参考 http://msdn2.microsoft.com/en-us/library/aa394373.aspx

列出当前的 Apache 实例

<?php
$wmi
= new COM('winmgmts://');
$processes = $wmi->ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'httpd.exe'");
foreach(
$processes as $process){
echo
$process->CommandLine . "<br />";
echo
$process->ProcessId . "<br />";
}
?>

参考 http://msdn2.microsoft.com/en-us/library/aa394372.aspx

在后台进程中运行 PHP 脚本

<?php
$dir
= "C:\\path\\to\\dir";
$php_path = "C:\\path\\to\\php.exe";
$file = "somescript.php";
//发送当前时间戳
$cmd_options = "-t " . time();
$wscript = new COM('WScript.Shell');
$wscript->Run("cmd /K CD $php_path $dir\\$file & ", 0, false);
?>

享受

汤姆
4
ferozzahid [at] usa [dot] com
20年前
要通过引用将参数传递给 COM 函数,您需要将 VARIANT 传递给它。像整数和字符串这样的常见数据类型对此不起作用。

例如,调用检索人员姓名的函数将如下所示

<?php
$Name
= new VARIANT;

$comobj = new COM("MyCOMOBj.Component") or die("无法创建 COM 组件");

if(!
$comobj->GetName($Name)) {
echo(
"无法检索名称");
}
else {
echo(
"检索到的名称为: " . $Name->value);
}
?>

$Name->type 将包含存储在 VARIANT 中的值的类型,例如 VT_BSTR。

注意适用于 PHP 5

代替 '$Name->value',我们可以只使用 '$Name' 来获取存储在 VARIANT 中的值。要获取存储在 VARIANT 中的值的类型,请使用 'variant_get_type($Name)'。

Feroz Zahid
2
Francois-R dot Boyer at PolyMtl dot ca
17 年前
我在尝试从 PHP 调用 Access VBA 脚本时遇到了问题;调用正在工作,但 Access 永远不会退出。问题是 Apache 服务器以 SYSTEM 身份运行,而不是我们通常用来运行 Office 的用户。并且,当用户第一次运行 Office 时,它会要求 SYSTEM 用户输入其姓名和首字母! ;-)

要解决此问题:停止 Apache,转到服务、Apache、属性、“登录”选项卡,然后选中“允许服务与桌面交互”。重新启动 Apache,然后打开您的 Office 应用程序,在 Apache 服务器加载的页面中,使用如下所示的小段 PHP 代码,

<?php
$app
= new COM("Access.Application"); // 或 Word.Application 或 Excel.Application ...
$app->Visible = true; // 以便我们在屏幕上看到窗口
?>

输入您想要的名称并退出应用程序。现在,下次您使用 PHP 中的 COM 对象加载 Office 应用程序时,它应该能够正确终止。如果您愿意,可以停止 Apache 取消选中“允许服务与桌面交互”,然后重新启动 Apache。我甚至不需要发送任何退出或任何内容到 Access,当 PHP 终止时,它会自动退出。

对于那些希望了解我如何调用 Access VBA 脚本的人,而不是使用 ODBC 或任何其他方法发送 SQL 请求(这似乎无法调用 VBA 脚本),我将数据库作为 COM 对象打开,它可以正常工作

<?php
$db_com
= new COM("文件路径名.mdb");
$result = $db_com->Application->Run("函数名", 'param1', 'param2', '...');
?>
1
naveed at php dot net
17 年前
这是一个拼写检查实现,它显示每个拼写错误单词的建议列表。

<?php
function SpellCheck($input)
{
$word=new COM("word.application") or die("无法创建 Word 对象");
$word->Visible=false;
$word->WindowState=2;
$word->DisplayAlerts=false;
$doc=$word->Documents->Add();
$doc->Content=$input;
$doc->CheckSpelling();
$result= $doc->SpellingErrors->Count;
if(
$result!=0)
{
echo
"输入文本包含拼写错误的单词。\n\n";
for(
$i=1; $i <= $result; $i++)
{
echo
"原始单词: " .$doc->SpellingErrors[$i]->Text."\n";
$list=$doc->SpellingErrors[$i]->GetSpellingSuggestions();
echo
"建议: ";
for(
$j=1; $j <= $list->Count; $j++)
{
$correct=$list->Item($j);
echo
$correct->Name.",";
}
echo
"\n\n";
}
}
else
{
echo
"未找到拼写错误。";
}
$word->ActiveDocument->Close(false);
$word->Quit();
$word->Release();
$word=null;
}

$str="Hellu world. There is a spellling error in this sentence.";
SpellCheck($str);
?>
1
alanraycom at el hogar dot net com
21 年前
使用 MSXML 的 XSLT 转换可以使用此代码完成

<?php
function xsltransform1($xslpath,$xmlstring)
{
$xml= new COM("Microsoft.XMLDOM");
$xml->async=false;
// $xmlstring 是一个 xml 字符串
$xml->load($xmlstring);
$xsl = new COM("Microsoft.XMLDOM");
$xsl->async=false;
// $xslpath 是 xsl 文件的路径
$xsl->load($xslpath);
$response=$xml->transformNode($xsl);
unset(
$xml);
unset(
$xsl);
return
$response;
}
?>

享受
艾伦·杨
2
madon at cma-it dot com
22年前
我认为这个 Excel 图表示例可能会有用。

请注意 Excel.application 与 Excel.sheet 的使用。

<pre>
<?php
print "Hi";
# 实例化电子表格组件。
# $ex = new COM("Excel.sheet") or Die ("未连接");
$exapp = new COM("Excel.application") or Die ("未连接");

# 获取应用程序名称和版本
print "应用程序名称:"{$ex->Application->value}<BR>" ;
print
"加载版本: "{$ex->Application->version}<BR>";

$wkb=$exapp->Workbooks->add();
#$wkb = $ex->Application->ActiveWorkbook or Die ("未打开工作簿");
print "我们打开了工作簿<BR>";

$ex->Application->Visible = 1; # 使 Excel 可见。
print "我们使 Excel 可见<BR>";

$sheets = $wkb->Worksheets(1); # 选择工作表
print "选择了工作表<BR>";
$sheets->activate; # 激活它
print "激活了工作表<BR>";

# 这是一个新的工作表
$sheets2 = $wkb->Worksheets->add(); # 添加一个工作表
print "添加了一个新的工作表<BR>";
$sheets2->activate; # 激活它
print "激活了工作表<BR>";

$sheets2->name="Report Second page";

$sheets->name="Report First page";
print
"我们为工作表设置了一个名称: "$sheets->name<BR>";

# 填充一列
$maxi=20;
for (
$i=1;$i<$maxi;$i++) {
$cell = $sheets->Cells($i,5) ; # 选择单元格(行号,列号)
$cell->activate; # 激活单元格
$cell->value = $i*$i; # 将其更改为 15000
}

$ch = $sheets->chartobjects->add(50, 40, 400, 100); # 创建一个图表对象

$chartje = $ch->chart; # 在图表对象中放置一个图表
$chartje->activate; # 激活图表对象
$chartje->ChartType=63;
$selected = $sheets->range("E1:E$maxi"); # 设置图表使用的数据
$chartje->setsourcedata($selected); # 设置图表使用的数据
print "设置了图表使用的数据 <BR>";

$file_name="D:/apache/Apache/htdocs/alm/tmp/final14.xls";
if (
file_exists($file_name)) {unlink($file_name);}
#$ex->Application->ActiveWorkbook->SaveAs($file_name); # 将工作表保存为 final.xls
$wkb->SaveAs($file_name); # 将工作表保存为 final.xls
print "已保存<BR>";

#$ex->Application->ActiveWorkbook->Close("False");
$exapp->Quit();
unset(
$exapp);
?>

</pre>

Alex Madon
2
匿名
18 年前
如果有人想从 DCOM 对象中获取 COM 对象,可以这样做

<?php
$dcom_obj
= new COM('dacom.object','remotehost') or die("无法获取 DCOM 对象!");
$com_obj = new Variant(NULL);
$dcom_obj->Get_Module($com_obj); // 用户函数,返回自定义 IDispatch(强制转换为 variant*)
?>

希望这能帮到一些人,因为我花了很长时间才弄明白。
1
a dot kulikov at pool4tool dot com
18 年前
如果您想知道如何在新建的 EXCEL 文件中对行或列进行分组,那么这可能对您有所帮助



<?php
/***
* 使用 COM 对象在 Excel 中视觉上对行进行分组
*
* 这并不容易,我花了几个小时尝试和错误才使
* 这个东西工作!!!
*
* @author Kulikov Alexey <[email protected]>
* @since 2006年3月13日
*
* @see 打开 Excel,按 Alt+F11,然后按 F2 -- 这是你的 COM 圣经
***/

// 启动 Excel
$excel = new COM("excel.application") or die("无法实例化 Excel");
print
"加载 Excel,版本 {$excel->Version}\n";

// 将其置于最前面
#$excel->Visible = 1;// 不需要

// 不希望出现警告... 静默运行
$excel->DisplayAlerts = 0;

// 创建一个新的工作簿
$wkb = $excel->Workbooks->Add();

// 选择默认工作表
$sheet=$wkb->Worksheets(1);

// 使其成为活动工作表
$sheet->activate;

// 用一些虚假数据填充它
for($row=1;$row<=7;$row++){
for (
$col=1;$col<=5;$col++){

$sheet->activate;
$cell=$sheet->Cells($row,$col);
$cell->Activate;
$cell->value = 'pool4tool 4eva ' . $row . ' ' . $col . ' ak';
}
// colcount for 循环结束
}

///////////
// 选择第 2 到 5 行
$r = $sheet->Range("2:5")->Rows;

// 对其进行分组,是的
$r->Cells->Group;

// 保存新文件
$strPath = 'tfile.xls';
if (
file_exists($strPath)) {unlink($strPath);}
$wkb->SaveAs($strPath);

// 关闭工作簿
$wkb->Close(false);
$excel->Workbooks->Close();

// 释放 RAM
unset($sheet);

// 关闭 Excel
$excel->Quit();

// 释放对象
$excel = null;
?>
1
Pedro Heliodoro
18 年前
使用 Windows Media Player OCX 和最新的 PHP 5.1 版本,我能够弹出 CD-ROM 驱动器。

<?php
// 创建 Windows Media Player 的实例
$mp = new COM("WMPlayer.OCX");
// 弹出驱动器列表中的第一个 CD-ROM
$mp->cdromcollection->item(0)->eject();

?>
2
angelo [at] mandato <dot> com
20年前
我创建的一些有用的 PHP 函数(类似于其他标准的 PHP 数据库函数),用于处理 ADO 数据源。


<?php
// ado.inc.php

$ADO_NUM = 1;
$ADO_ASSOC = 2;
$ADO_BOTH = 3;

function
ado_connect( $dsn )
{
$link = new COM("ADODB.Connection");
$link->Open($dsn);
return
$link;
}

function
ado_close( $link )
{
$link->Close();
}

function
ado_num_fields( $rs )
{
return
$rs->Fields->Count;
}

function
ado_error($link)
{
return
$link->Errors[$link->Errors->Count-1]->Number;
}

function
ado_errormsg($link)
{
return
$link->Errors[$link->Errors->Count-1]->Description;
}

function
ado_fetch_array( $rs, $result_type, $row_number = -1 )
{
global
$ADO_NUM, $ADO_ASSOC, $ADO_BOTH;
if(
$row_number > -1 ) // Defined in adoint.h - adBookmarkFirst = 1
$rs->Move( $row_number, 1 );

if(
$rs->EOF )
return
false;

$ToReturn = array();
for(
$x = 0; $x < ado_num_fields($rs); $x++ )
{
if(
$result_type == $ADO_NUM || $result_type == $ADO_BOTH )
$ToReturn[ $x ] = $rs->Fields[$x]->Value;
if(
$result_type == $ADO_ASSOC || $result_type == $ADO_BOTH )
$ToReturn[ $rs->Fields[$x]->Name ] = $rs->Fields[$x]->Value;
}
$rs->MoveNext();
return
$ToReturn;
}

function
ado_num_rows( $rs )
{
return
$rs->RecordCount;
}

function
ado_free_result( $rs )
{
$rs->Close();
}

function
ado_query( $link, $query )
{
return
$link->Execute($query);
}

function
ado_fetch_assoc( $rs, $row_number = -1 )
{
global
$ADO_ASSOC;
return
ado_fetch_array( $rs, $ADO_ASSOC, $row_number);
}

function
ado_fetch_row( $rs, $row_number = -1 )
{
global
$ADO_NUM;
return
ado_fetch_array( $rs, $ADO_NUM, $row_number);
}

// 其他函数:
function ado_field_len( $rs, $field_number )
{
return
$rs->Fields[$field_number]->Precision;
}

function
ado_field_name( $rs, $field_number )
{
return
$rs->Fields[$field_number]->Name;
}

function
ado_field_scale( $rs, $field_number )
{
return
$rs->Fields[$field_number]->NumericScale;
}

function
ado_field_type( $rs, $field_number )
{
return
$rs->Fields[$field_number]->Type;
}

?>

aod 版本是一个拼写错误。
1
[email protected]
16 年前
使用 Word 2003 COM 对象。

您是否尝试过使用 Word.Application COM,并且 Word 文档崩溃,PHP 脚本挂起?

事实证明,Office COM 对象中存在一个问题,它不允许 Web 应用程序(IIS、Apache)脚本引擎在实例化 COM 后释放该对象。Service Pack 3 Office 更新声称可以解决此问题。将进行测试并发布结果。
1
[email protected]
19 年前
如果您使用的是打开窗口或对话框的 COM 对象(如 Office 应用程序),则即使使用以下代码,这些窗口或对话框也不会出现,并且会保持不可见状态

$word->visible = true;

要解决此问题,请转到 Web 服务属性(管理工具)并单击(在“登录”选项卡中)“允许服务与桌面交互”。

这解释了许多关闭应用程序的问题。当您尝试关闭时,询问是否保存文件的对话框必须出现,但只有在“允许服务与桌面交互”选项打开时才会出现。

希望对您有所帮助。
1
[email protected]
19 年前
简单地将 xls 转换为 csv


<?php
// 开始使用 Excel
$excel = new COM("excel.application") or die("无法实例化 Excel");
print
"加载 Excel,版本 {$excel->Version}\n";

// 将 Excel 窗口置于最前
#$excel->Visible = 1;//无需
// 不需要警告... 静默运行
$excel->DisplayAlerts = 0;

// 打开文档
$excel->Workbooks->Open("C:\\mydir\\myfile.xls");
//XlFileFormat.xlcsv 文件格式为 6
// saveas 命令 (文件,格式 ......)
$excel->Workbooks[1]->SaveAs("c:\\mydir\\myfile.csv",6);

// 关闭 Excel
$excel->Quit();

// 释放对象
$excel->Release();
$excel = null;
?>
1
michael at example dot com
19 年前
在与 IIS 6/Windows 2003 和 PHP 5.0.2 进行了大量尝试后,我终于找到了如何使用 Imagemagick COM+/OLE 接口的方法。似乎您必须在每次 convert() 后重新创建 COM 对象,否则它有时会以非常奇怪的错误失败,因为 PHP COM 接口不像旧的 ASP 接口那样稳定。
1
匿名用户
19 年前
如果您想使用 Excel 添加新的超链接

<?php
$cell
=$sheet->Range('O'.$j);
$cell->Hyperlinks->Add($cell ,'here_your_file');
?>

我写下这段说明是因为很难找到
实现此功能的正确方法。

非常感谢
1
Shawn Coppock
20年前
对于我们这些不是对象模型专家的用户,如果您有 Microsoft Excel 或 Microsoft Word 可用,请进入 Visual Basic 编辑器 (Alt+F11)。现在,您可以打开对象浏览器窗口 (F2) 并查看您能找到什么。

如果您在对象浏览器中选择“Word”,则该类的类和成员将在下方显示。例如,如果您在类列中单击“Selection”,然后在成员列中单击“Font”,则您将在底部看到“Property Font As Font Member of Word.Selection”显示。单击那里的“Font”链接。

在类列中再次单击 Word“Selection”,然后在成员列中单击“PageSetup”,您将在底部看到“Property PageSetup As PageSetup Member of word.Selection”显示。单击那里的“PageSetup”链接。

使用上述示例,您现在可以从 php 中构建 Word 文档。这是一个简单的示例,根据页边距设置创建 1 & 1/2" 的文本间距,并使用深红色文本和 8pt Helvetica 字体。

<?php
$content
= "在此处插入示例文本\n\n这将开始一个新的段落行。";
$word= new COM("word.application") or die("无法创建 Word 文档");
print
"加载 Word,版本 {$word->Version}\n";
$word->Visible = 0;
$word->Documents->Add();
$word->Selection->PageSetup->LeftMargin = '3"';
$word->Selection->PageSetup->RightMargin = '4"';
$word->Selection->Font->Name = 'Helvetica';
$word->Selection->Font->Size = 8;
$word->Selection->Font->ColorIndex= 13; //wdDarkRed = 13
$word->Selection->TypeText("$content");
$word->Documents[1]->SaveAs("some_tst.doc");
$word->quit();
echo
"完成";
?>

这个示例(以及其他示例)在我的 Microsoft Word 10.0 对象库(MS Word 2002)、Apache 和 Windows XP 上的 PHP 上运行正常。使用 Visual Basic 编辑器进行实验将产生一些令人惊叹的 PHP 文档,因为它将帮助您了解所用对象的关联,并让您了解如何构建代码。但是,如果您的代码完全偏离轨道,请准备好偶尔出现 PHP.exe 崩溃的情况。

希望这有帮助!
1
mark dickens at mindspring dot com
20年前
只是想提醒那些希望在 Windows 2000/XP 下使用 COM 与打印机交互的用户。如果它不起作用或似乎挂起,请尝试更改 Apache(假设您使用的是 Apache)服务运行的登录标识,从系统帐户更改为另一个帐户。默认情况下,大多数服务都将安装为在系统帐户下运行,尽管系统帐户对它所运行的计算机具有完全权限,但据我所知,它在该范围之外没有任何权限。显然,访问打印机被认为是“超出范围”。我使用了此技术将 Dymo 热敏标签打印机与我的服务器连接,现在它可以正常工作了。
1
chris at hitcatcher dot com
21 年前
许多 COM 对象在将长(win32)文件名作为函数参数传递时表现不佳。您可以在大多数(某些 win 平台不支持,并且出于性能原因可以在注册表中将其关闭)服务器上使用以下方法获取文件夹或文件的 8.3 名称

<?php
// 创建 FSO 实例
$exFSO = new COM("Scripting.FileSystemObject") or die ("无法创建 Scripting.FileSystemObject");

// 设置变量
$myDir = "C:\\Program Files\\";
$myFile = "a long file name.txt";

// 获取文件夹和文件对象
$exDir = $exFSO->GetFolder($myDir);
$exFile = $exFSO->GetFile($myDir . $myFile);
echo
$exDir->ShortPath;
echo
$exFile->ShortPath;
?>
1
匿名用户
21 年前
这是一个读取存储在 MS Office 和其他 Windows 文件中的自定义属性(如作者、关键字等)的示例。您必须安装并注册 dsofile,如 http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q224351. 中所述。该发行版中的 .frm 文件列出了大多数可用的属性。

<?php
// 您要访问的文件
$fn = '/docs/MFA.xls';

$oFilePropReader = new COM('DSOleFile.PropertyReader');
$props = $oFilePropReader->GetDocumentProperties($fn);

// 一种语法
$au = com_get($props, 'Author');
print
"au: $au \n";

// 另一种语法
$str = 'LastEditedBy';
$lsb = $props->$str;
var_dump($lsb);

// 如果需要,可以设置属性
if (!$props->IsReadOnly()) {
$props->Subject = 'tlc';
}
?>
1
php at dictim dot com
21 年前
我花了几天时间才弄清楚如何做,所以必须分享一下

如何从 MS Word 文档中获取字数



<?php
#实例化 Word 组件。

$word = new COM("word.application") or die("无法实例化 Word");

$word->Visible = 1;

$word->Documents->Open("c:/anydocument.doc");
$temp = $word->Dialogs->Item(228);
$temp->Execute();
$numwords = $temp->Words();

echo
$numwords;

$word->Quit();
?>

请注意,这是唯一能够准确获取字数的方法
$word->ActiveDocument->Words->Count;
会将所有回车符和标点符号都视为单词,因此非常不准确。
1
tedknightusa at hotmail dot com
22年前
一个 Notes 示例

<?php
$session
= new COM "Lotus.NotesSession" );
$session->Initialize($password);

$someDB = "C:\Lotus\Notes\Data\somedb.nsf";
$db = $session->GetDatabase("", $someDB) or die("无法获取 somedb.nsf");
$view = $db->GetView("some_view") or die("未找到 Some View");

$doc = $view->GetFirstDocument() or die("无法获取初始 Some 文档");

// 循环遍历
while($doc){
$col_vals = $doc->ColumnValues();
echo
$col_vals[0];
$doc = $view->GetNextDocument($doc);
}
?>
1
dwt at myrealbox dot com
22年前
在第一次编写实例化 COM 对象的应用程序时,我总是面临实例化程序无法正确终止的问题,尽管其他所有操作都正常。事实上,必须使用任务管理器手动终止进程。在进行一些实验后,我能够将这种特殊行为的原因隔离出来,如下面的示例代码所示

<?php

//通过函数 ArrayName(Index) 获取元素来访问数组可以工作,但肯定既不高效也不符合良好的风格
$excel=new COM("Excel.Application");
$excel->sheetsinnewworkbook=1;
$excel->Workbooks->Add();

$book=$excel->Workbooks(1);
$sheet=$book->Worksheets(1);

$sheet->Name="Debug-Test";
$book->saveas("C:\\debug.xls");

$book->Close(false);
unset(
$sheet);
unset(
$book);
$excel->Workbooks->Close();
$excel->Quit();
unset(
$excel);

//像往常一样访问数组(使用 [] 运算符)可以工作,但会导致应用程序无法自行终止
$excel=new COM("Excel.Application");
$excel->sheetsinnewworkbook=1;
$excel->Workbooks->Add();

$excel->Workbooks[1]->Worksheets[1]->Name="Debug-Test";
$excel->Workbooks[1]->saveas("C:\\debug.xls");

$excel->Workbooks[1]->Close(false);
$excel->Workbooks->Close();
$excel->Quit();
unset(
$excel);

?>

示例代码两次执行相同的操作,每次都正确创建文件。然而,由于某些神秘的原因,一旦您以大多数程序员(尤其是那些大量使用 C++ 进行 OOP 的程序员)的方式访问数组,实例化的 Excel 进程就不会终止!因此,在 PHP 开发人员意识到这个问题之前,我们将不得不使用第一个示例中说明的低效编码风格。
0
larrywalker at at chelseagroton dot com
16 年前
要在后台进程中运行 php 脚本并传递变量,可以使用

<?php

$WshShell
= new COM("WScript.Shell");
$oExec = $WshShell->Run("c:\\xampp\\php\\php.exe

c:\\xampp\\Not_on_Web\\ftptestback.php --user=
$username", 7, false);

?>

对我有用。
0
kiotech at hotmail dot com
18 年前
这是一个使用 PHP 参数的代码示例

<?php
$ObjectFactory
= New COM("CrystalReports11.ObjectFactory.1");
$crapp = $ObjectFactory->CreateObject("CrystalDesignRunTime.Application");
$creport = $crapp->OpenReport("//report1.rpt", 1);


$z= $creport->ParameterFields(1)->SetCurrentValue("Mango");
$z= $creport->ParameterFields(2)->SetCurrentValue(5000);

$creport->ExportOptions->DiskFileName="reportin.pdf";
$creport->ExportOptions->PDFExportAllPages=true;
$creport->ExportOptions->DestinationType=1; $creport->ExportOptions->FormatType=31;
$creport->Export(false);

$len = filesize("reportin.pdf");
header("Content-type: application/pdf");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=reportin.pdf");
readfile("reportin.pdf");
?>
0
sorin dot andrei at mymail dot ro
20年前
[编辑注
序列化对象,存储它,然后(在下一页)反序列化它将起作用。
结束注]

PHP 的一大问题是它无法在会话中保存 COM 对象

一个示例代码在这里。这仅在第一次有效,然后给出错误
在第 $mMap->Refresh(); 行调用未定义的方法 com::Refresh()
原因是他无法在会话中保存对象 $mMap

<?php
session_start
();
if (isset(
$_SESSION['map'])) {
$mMap = $_SESSION['map'];
}
else
{
$ArcIMSConnector = new COM ("aims.ArcIMSConnector") or die("无法创建AIMS消息对象");
echo
"已加载ArcIMSConnector,<br>";
$ArcIMSConnector->ServerName = "map.sdsu.edu";
$ArcIMSConnector->ServerPort = 5300;

$mMap = new COM ("aims.Map") or die("无法创建aims.Map消息对象");
echo
"已加载aims.Map,<br>";
print
"AIMS-ServerName= $ArcIMSConnector->ServerName <br>";

$resultInit= $mMap->InitMap($ArcIMSConnector,"Worldgeography");

$mMap->Width = 400; // '地图宽度(像素)
$mMap->Height = 300; // '地图高度(像素)
$mMap->BackColor = 15130848;
$_SESSION['map'] = $mMap;
}

$resultRefresh = $mMap->Refresh(); //刷新地图
$urlImage = $mMap->GetImageAsUrl();
print
"<br>urlImage=$urlImage<br>";

print
"<br><IMG SRC='$urlImage'>";

/*
$ArcIMSConnector->Release();
$ArcIMSConnector = null;

$mMap->Release();
$mMap = null;
*/

?>
0
brana
21 年前
如何通过MAPI发送邮件(适用于Windows NT4,Apache作为服务启动)

<?php
# 新建MAPI会话...
$session = new COM("MAPI.Session");

# 登录
$strProfileInfo = "exchange_server" . chr(10) . "exchange_user";
$session->Logon("", "", 0, 1, 0, 1, $strProfileInfo);

# 新建邮件...
$msg = $session->Outbox->Messages->Add();
$msg->Subject = "主题";
$msg->Text = "邮件正文";

# 设置收件人...
$rcpts = $msg->Recipients;
$rcpts->AddMultiple("[email protected]", 1); # 收件人...
$rcpts->AddMultiple("[email protected]", 2); # 抄送...
$rcpts->AddMultiple("[email protected]", 3); # 密送...

# 解析发件人
$rcpts->Resolve();

# 发送邮件
$msg->Send();

# 注销
$session->Logoff();

# 清理
if($msg!=null) {
$msg->Release();
$msg = null;
}
if(
$session!=null) {
$session->Release();
$session = null;
}
?>

ps:启动服务的NT账户和Exchange用户必须匹配!
0
richard dot quadling at carval dot co dot uk
21 年前
感谢Harald Radi和Wez Furlong。

一些VBA函数具有可选参数。有时您要传递的参数不是连续的。

例如:

GoTo What:=wdGoToBookmark, Name="BookMarkName"
GoTo(wdGoToBookmark,,,"BookMarkName)

在PHP中,"空白"参数需要为空。

也就是...

<?php
// 某些服务器可能具有自动超时,因此可以根据需要设置任意长的超时时间。
set_time_limit(0);

// 在开发过程中显示所有错误、警告和通知。
error_reporting(E_ALL);

// 用作某些COM函数中不需要参数时的占位符。
$empty = new VARIANT();

// 加载相应的类型库。
com_load_typelib('Word.Application');

// 创建一个要使用的对象。
$word = new COM('word.application') or die('无法加载Word');
print
"已加载Word,版本 {$word->Version}\n";

// 打开一个包含YourName和YourAge书签的新文档。
$word->Documents->Open('C:/Unfilled.DOC');

// 填写表单中的信息。
$word->Selection->GoTo(wdGoToBookmark,$empty,$empty,'YourName'); // 注意使用类型库中的wdGoToBookmark和$empty。
$word->Selection->TypeText($_GET['YourName']);

$word->Selection->GoTo(wdGoToBookmark,$empty,$empty,'YourAge');
$word->Selection->TypeText($_GET['YourAge']);

// 保存文档,关闭Word并结束。
$word->Documents[1]->SaveAs("C:/{$_GET['YourName']}.doc");
$word->Quit();
$word->Release();
$word = null;
print
"Word已关闭。\n";
?>

示例文档为...

您好 [YourName书签],您 [YourAge书签] 岁。

并且将被称为...

word.php?YourName=Richard%20Quadling&YourAge=35

此致,

Richard。
0
pchason at juno dot com
21 年前
搜索了几天如何设置一个多列HTML输出网格,该网格在创建ADODB连接时不使用数组。找不到合适的解决方案,所以我自己想出了一个。非常简单。真希望我早点自己尝试一下。下面是带有数据库连接的注释代码...

<html>
<body>
<table>
<?php
// 创建数据库连接
$conn = new COM("ADODB.Connection");
$dsn = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" . realpath("mydb.mdb");
$conn->Open($dsn);
// 通过SQL字符串获取数据
$rs = $conn->Execute("select clients from web");
$clients = $rs->Fields(1);
// 开始多列数据输出
$i = 0;
$columns = 5;
while (!
$rs->EOF){
// 如果$i等于0,开始一行
if($i == 0){
echo
"<tr>";
}
// 然后开始写入单元格,将$i加1,并移动到下一条记录
echo "<td>" . $clients->value . "</td>";
$i++;
$rs->movenext();
// 一旦$i递增到等于$columns,结束行,
// 并通过将$i设置为0重新开始该过程
if($i == $columns || $rs->EOF) {
echo
"</tr>";
$i = 0;
}
}
// 结束多列数据输出

// 关闭ADO连接并释放资源
$rs->Close();
$conn->Close();
$rs = null;
$conn = null; ?>
</table>
</body>
</html>
-1
php at racinghippo dot co dot uk
21 年前
通过引用传递/返回参数
=========================================

某些COM函数不仅通过返回值返回数值,而且还会对作为参数*通过引用*传递给它的变量进行操作。

RetVal = DoSomethingTo (myVariable)

仅仅在myVariable前面加上“&”不起作用 - 您需要传递一个正确类型的变体,如下所示

$myStringVariant = new VARIANT("over-write me", VT_BSTR);
$result = $comobj->DoSomethingTo( &$myStringVariant );

然后可以通过以下方式检索变体中的值:

$theActualValue = $myStringVariant->value;

可以根据您的需求创建其他类型的变体 - 请参阅前面有关VARIANT类型的部分。
To Top