PHPExcel是一个开源的第三方PHP类库,顾名思义,使用PHPExcel可以实现通过编写PHP代码来完成各种复杂的excel操作,由于最近公司有一个批量更新LDAP信息的需求,因此决定使用PHPExcel来读取存放要更新属性的excel文件,再使用ldap模块提供的函数更新相应的ldap条目。

一、先引入必要的连接文件和PHPexcel类库

require_once('../includes/connect.php');
require_once('../includes/functions.php');

/**包含PHPexcel类库*/ 
require_once('../classes/PHPExcel.php');
require_once('../classes/PHPExcel/Writer/Excel2007.php');
require_once('../classes/PHPExcel/Writer/Excel5.php');
require_once('../classes/PHPExcel/IOFactory.php');

/**excel文件名称*/ 
$excel_filename='update_info.xlsx';

/**是否处于调试状态*/ 
$debug=true;

/**excel文件路径*/ 
$dirname=dirname(__FILE__).'/../'.$excel_filename;

/**LDAP重点额根dn*/ 
$base_dn='dc=company,dc=net';

/**实例化一个读取器*/ 
$PHPReader = new PHPExcel_Reader_Excel2007(); 

/**如果excel文件不可读*/  
if(!$PHPReader->canRead($dirname)){  
    $PHPReader = new PHPExcel_Reader_Excel5();  
    if(!$PHPReader->canRead($dirname)){  
        return false;
        exit();
    }  
}

二、初始化读取excel中有用的信息

/**载入excel文件*/ 
$PHPExcel = $PHPReader->load($dirname);

/**读取excel文件中的第一个工作表*/  
$currentSheet = $PHPExcel->getSheet(0);  

/**取得最大的列号*/  
$allColumn = $currentSheet->getHighestColumn(); 

/**取得一共有多少行*/  
$allRow = $currentSheet->getHighestRow(); 

/**定义三个空数组存放不同的更新结果*/  
$inexistent_user=$dismiss_user=$updated_user=array();

三、主循环逐行读取excel中的信息,根据具体信息更新ldap

for ($row=2; $row <= $allRow; $row++) 
{ 
    //读取A列为工号
    $employeenumber=$currentSheet->getCell('A'.$row)->getValue(); 

    //富文本处理
    ($employeenumber instanceof PHPExcel_RichText) and ($employeenumber = $employeenumber->__toString());

    //如果读取到的工号没有从更目录中找到
    if (!is_employeenumber_in_ou($conn, 'dc=company,dc=net', $employeenumber)) {
        $inexistent_user[]=$employeenumber;
        continue;
    }

    //如果读取到的工号的员工已经离职
    if (is_employeenumber_in_ou($conn, 'ou=Dimission,dc=company,dc=net', $employeenumber)) {
        $dismiss_user[]=$employeenumber;
        continue;
    }

    $dn=get_dn_by_employeenumber($conn, $base_dn, $employeenumber);

    //读取B列为座位号
    $old_seatnumber=get_seatnumber_by_dn($conn, $dn);
    $new_seatnumber=$currentSheet->getCell('B'.$row)->getValue();
    ($new_seatnumber instanceof PHPExcel_RichText) and ($new_seatnumber = $new_seatnumber->__toString());

    //"stay"标志表示属性保持不变,不做更新,"zero"表示更新该属性为0
    if ($new_seatnumber=='stay') {
        $new_seatnumber=$old_seatnumber;
    }

    if ($new_seatnumber=='zero') {
        $new_seatnumber=0;
    }

    //读取C列为电话短号
    $old_telephonenumber=get_telephonenumber_by_dn($conn, $dn);
    $new_telephonenumber=$currentSheet->getCell('C'.$row)->getValue();
    ($new_telephonenumber instanceof PHPExcel_RichText) and ($new_telephonenumber = $new_telephonenumber->__toString());
    if ($new_telephonenumber=='stay') {
        $new_telephonenumber=$old_telephonenumber;
    }

    if ($new_telephonenumber=='zero') {
        $new_telephonenumber=0;
    }

    //读取D列为电话长号
    $old_homephone=get_homephone_by_dn($conn, $dn);
    $new_homephone=$currentSheet->getCell('D'.$row)->getValue();
    ($new_homephone instanceof PHPExcel_RichText) and ($new_homephone = $new_homephone->__toString());
    if ($new_homephone=='stay') {
        $new_homephone=$old_homephone;
    }

    if ($new_homephone=='zero') {
        $new_homephone=0;
    }

    //读取E列为手机号
    $old_mobile=get_mobile_by_dn($conn, $dn);
    $new_mobile=$currentSheet->getCell('E'.$row)->getValue();
    ($new_mobile instanceof PHPExcel_RichText) and ($new_mobile = $new_mobile->__toString());
    if ($new_mobile=='stay') {
        $new_mobile=$old_mobile;
    }

    if ($new_mobile=='zero') {
        $new_mobile=0;
    }

    $attrs_to_update=array(
            'seatnumber'=>$new_seatnumber,
            'telephonenumber'=>$new_telephonenumber,
            'homephone'=>$new_homephone,
            'mobile'=>$new_mobile
        );

    print_r($attrs_to_update);
    echo "&lt;br /&gt;";

    if (!$debug) 
    {
        //开始更新属性
        $mod_result=ldap_modify($conn, $dn, $attrs_to_update);

        if ($mod_result) {
            $updated_user[]=$employeenumber;
        }

    }

}

四、更新完成后,打印更新记录

echo "更新".$excel_filename."中的员工信息完成!!!<br />";
echo "#############################################<br />;
echo "共读取到有效数据".($allRow-1)."行&lt;<br />"

echo "#############################################<br />";
echo "信息成功更新的记录条数:".count($updated_user)."<br />";

echo "#############################################<br />";
echo "发现LDAP中不存在的无效记录条数:".count($inexistent_user)."<br />";
if (count($inexistent_user)>0) {
    print_r($inexistent_user);
}

echo "#############################################<br />";
echo "发现已经离职的记录条数:".count($dismiss_user)."<br />";
if (count($dismiss_user)>0) {
    print_r($dismiss_user);
}

//释放ldap连接
ldap_close($conn);

五、functions.php中封装的一些操作ldap函数

/**
 * 判断工号是否存在于指定的ou中
 * @param  [type]  $conn           ldap连接资源
 * @param  [type]  $ou             要检索的ou
 * @param  [type]  $employeenumber 工号
 * @return boolean                 存在返回true,否则返回false
 */
function is_employeenumber_in_ou($conn, $ou, $employeenumber)
{
    $result=ldap_search($conn, $ou, "employeeNumber=$employeenumber");
    if (ldap_count_entries($conn, $result)==0) {
        return false;
    }
    else{
        return true;
    }
}

/**
 * 通过工号获取完整dn信息
 * @param  [type] $conn           ldap连接资源
 * @param  [type] $base_dn        根dn
 * @param  [type] $employeenumber 工号
 * @return [type]                 获取成功返回字符串工号,否则返回false
 */
function get_dn_by_employeenumber($conn, $base_dn, $employeenumber)
{
    $dn=search_dn_by_filter($conn, $base_dn, "employeenumber=$employeenumber");
    if(count($dn)==1){
        return $dn[0];
    }
    else{
        return false;
    }
}

/**
 * 读取指定dn条目的座位号信息,之后获取联系电话、手机号等信息的思路相同
 * @param  [type] $conn ldap连接资源
 * @param  [type] $dn   dn条目
 * @return [type]       读取成功则返回字符串,否则返回null
 */
function get_seatnumber_by_dn($conn, $dn)
{
    $result=ldap_read($conn, $dn, "(objectClass=*)", array("seatNumber"));
    $entries=ldap_get_entries($conn, $result);
    if ($entries["count"]==0) {
        return NULL;
    } else {
        return $entries[0]["seatnumber"][0];
    }
}