COM 函数

另请参阅

有关 COM 的更多信息,请阅读 » COM 规范。你可以在我们的 PHP 和 COM 常见问题解答中找到一些额外的有用信息。如果你考虑在服务器端使用 MS Office 应用程序,你应该阅读这里的说明:» Office 服务器端自动化的注意事项

目录

添加笔记

用户贡献笔记 31 笔记

9
Sorin Negulescu
7 年前
我花了很多时间试图让 word.application 在使用 Apache 作为服务的 Windows 服务器上运行。
如果从命令行启动 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 选项默认设置为“关闭”,并且未来的版本可能不再支持该选项。
一些 COM 函数具有按引用传递的参数。VARIANT 对象必须用于调用这些函数,但它将在变量名前没有“&”的情况下传递。

示例

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

/* 有效 */
$result = $comobj->DoSomethingTo($myStringVariant );

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

/* 可以通过以下方式检索变体中的值: */
$theActualValue = $myStringVariant->value;
?>
4
tomfmason at nospam-gmail dot com
16 年前
要获取 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
19 年前
要通过引用将参数传递给 COM 函数,您需要将 VARIANT 传递给它。 整数和字符串等常见数据类型将不适用于此。

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

<?php
$Name
= new VARIANT;

$comobj = new COM("MyCOMOBj.Component") or die("Couldn't create the COM Component");

if(!
$comobj->GetName($Name)) {
echo(
"Could not retrieve name");
}
else {
echo(
"The name retrieved is : " . $Name->value);
}
?>

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

注意对于 PHP 5

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

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

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

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

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

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

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

<?php
function SpellCheck($input)
{
$word=new COM("word.application") or die("Cannot create Word object");
$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
"Input text contains misspelled words.\n\n";
for(
$i=1; $i <= $result; $i++)
{
echo
"Original Word: " .$doc->SpellingErrors[$i]->Text."\n";
$list=$doc->SpellingErrors[$i]->GetSpellingSuggestions();
echo
"Suggestions: ";
for(
$j=1; $j <= $list->Count; $j++)
{
$correct=$list->Item($j);
echo
$correct->Name.",";
}
echo
"\n\n";
}
}
else
{
echo
"No spelling mistakes found.";
}
$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
20 年前
可以使用此代码完成使用 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 ("Did not connect");
$exapp = new COM("Excel.application") or Die ("Did not connect");

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

$wkb=$exapp->Workbooks->add();
#$wkb = $ex->Application->ActiveWorkbook or Die ("Did not open workbook");
print "we opened workbook<BR>";

$ex->Application->Visible = 1; # 使 Excel 可见。
print "we made excell visible<BR>";

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

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

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

$sheets->name="Report First page";
print
"We set a name to the sheet: $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 "set the data the chart uses <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 "saved<BR>";

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

</pre>

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

<?php
$dcom_obj
= new COM('dacom.object','remotehost') or die("Unable to get DCOM object!");
$com_obj = new Variant(NULL);
$dcom_obj->Get_Module($com_obj); // 用户函数,返回自定义 IDispatch(作为 variant* 转换)
?>

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

<?php
/***
* 在 Excel 中使用 COM 对象在视觉上对行进行分组
*
* 这并不容易,我花了几个小时的反复试验才使
* 此功能正常工作!!!
*
* @author Kulikov Alexey <[email protected]>
* @since 13.03.2006
*
* @see 打开 Excel,按 Alt+F11,然后按 F2 -- 这是您的 COM 圣经
***/

// 启动 Excel
$excel = new COM("excel.application") or die("Unable to instanciate excel");
print
"Loaded excel, version {$excel->Version}\n";

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

// 不希望出现警告...静默运行
$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';
}
// end of colcount for loop
}

///////////
// 选择第 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();

// 释放内存
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 ) // 定义在 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
monica at digitaldesignservices dot com
16 年前
使用 Word 2003 COM 对象。

你是否尝试过使用 Word.Application COM,结果 Word 文档崩溃,PHP 脚本卡住了?

事实证明,Office COM 对象中存在一个问题,它不允许 Web 应用程序(IIS、Apache)脚本引擎在实例化 COM 后释放对象。Office Service Pack 3 更新声称可以解决这个问题。我会测试并发布结果。
1
allan666 at gmail dot com
18 年前
如果你正在使用打开窗口或对话框的 COM 对象(如 Office 应用程序),这些窗口或对话框将不会出现,即使你使用类似以下代码:

$word->visible = true;

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

这解释了许多关闭应用程序的问题。当你尝试关闭时,会弹出一个询问你是否要保存文件的对话框,但只有在“允许与桌面交互”选项开启的情况下才会出现。

希望对您有所帮助。
1
bruce at yourweb dot com dot au
19 年前
将 xls 简单转换为 csv
<?php
// 启动 Excel
$excel = new COM("excel.application") or die("无法实例化 Excel");
print
"加载 Excel,版本 {$excel->Version}\n";

// 将其置于最前面
#$excel->Visible = 1;//NOT
// 不要出现警报 ... 静默运行
$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 & PHP 在 Windows XP 上运行。使用 Visual Basic 编辑器进行实验将产生一些惊人的文档,因为它将帮助你了解所用对象的关联关系,并让你了解如何构建你的代码。但如果你的代码完全偏离了方向,请准备好偶尔发生的 PHP.exe 崩溃。

希望这有帮助!
1
mark dickens at mindspring dot com
20 年前
一个关于在 Windows 2000/XP 下使用 COM 连接到打印机的注意事项。如果它不起作用或似乎挂起,请尝试更改 Apache(假设你使用的是 Apache)服务运行的登录身份,从系统帐户更改为另一个帐户。默认情况下,大多数服务将安装为在系统帐户下运行,尽管系统帐户对它运行的计算机具有完全权限,但据我所知,它在该范围之外没有任何权限。显然访问打印机被认为是“超出范围”。我使用这种技术将 Dymo 热敏标签打印机连接到我的服务器,现在它可以正常工作了。
1
chris at hitcatcher dot com
20 年前
许多 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
匿名
20 年前
以下是如何读取存储在 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
20 年前
我花了几天时间才弄清楚如何做,所以我要分享一下

如何从 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
21 年前
一个 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
21 年前
在第一次编写实例化 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);

?>

示例代码两次执行相同的操作,并且每次都会正确创建文件。然而,由于某些神秘的原因,实例化的 excel 进程在以大多数程序员(尤其是那些在 c++ 中进行大量 oop 的程序员)的方式访问数组后,将无法自行终止!因此,在 PHP 开发人员意识到这个问题之前,我们将不得不使用第一个示例中所示的低效编码风格。
0
larrywalker at at chelseagroton dot com
15 年前
要在后台进程中运行 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
19 年前
[编辑注
序列化对象,存储它,然后(在下一页)反序列化它将起作用。
结束注]

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

示例代码如下。这仅在第一次有效,然后会报错
调用未定义的方法 com::Refresh() 在行 $mMap->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
20 年前
如何通过 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 年前
在创建 ADODB 连接时,我搜索了几天,试图找到一种不使用数组的设置多列 HTML 输出网格的方法。 我没有找到,所以我自己想出来了。 很简单。 我希望自己早点尝试。 以下是带数据库连接的注释代码...

<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
racinghippo dot co dot uk 处的 php
21 年前
通过引用传递/返回参数
=========================================

一些 COM 函数不仅通过返回值返回结果,还会通过 *引用* 传递给它的变量来操作。

RetVal = DoSomethingTo (myVariable)

在 myVariable 前面简单地添加一个 '&' 并不起作用 - 您需要传递给它一个正确类型的变体,如下所示

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

然后可以通过以下方式获取变体中的值

$theActualValue = $myStringVariant->value;

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