php怎么把数据表中的数据导出到excel表中

 更新时间:2016年11月25日 16:35  点击:1490
很多时候,数据库中的数据需要导出成excel,以下是最简便的方法,不用导出excel的类,即使功能简单,但是对于没有复杂需求的项目“见效快”。

先定义头部信息,表示输出一个excel。然后再以table的形式把数据库的信息循环的echo出来,就好了。

 代码如下 复制代码

<?php

 

 header("Content-type:application/vnd.ms-excel");

 header("Content-Disposition:filename=xls_region.xls");

 $cfg_dbhost = 'localhost';

 $cfg_dbname = 'testdb';

 $cfg_dbuser = 'root';

 $cfg_dbpwd = 'root';

 $cfg_db_language = 'utf8';

 // END 配置

 


 //链接数据库

 $link = mysql_connect($cfg_dbhost,$cfg_dbuser,$cfg_dbpwd);

 mysql_select_db($cfg_dbname);

 //选择编码 www.111Cn.net

 mysql_query("set names ".$cfg_db_language);

 

 //users表

 $sql = "desc users";

 

 $res = mysql_query($sql);

 echo "<table><tr>";

 //导出表头(也就是表中拥有的字段)

 while($row = mysql_fetch_array($res)){

  $t_field[] = $row['Field']; //Field中的F要大写,否则没有结果

  echo "<th>".$row['Field']."</th>";

 }

 echo "</tr>";

 //导出100条数据

 $sql = "select * from users limit 100";

 $res = mysql_query($sql);

 while($row = mysql_fetch_array($res)){

  echo "<tr>";

  foreach($t_field as $f_key){

   echo "<td>".$row[$f_key]."</td>";

  }

  echo "</tr>";

 }

 echo "</table>";

 

?>

 

文章详细介绍了csv文件在php中快速导入到mysql数据库中的例子,虽然从最简单的几百MB的到最后使用插件实现几个GB数据导入中间有一些嗑碰了,但结果还是好的。

对于数百万条数据量的CSV文件,文件大小可能达到数百M,如果简单读取的话很可能出现超时或者卡死的现象。

为了成功将CSV文件里的数据导入数据库,分批处理是非常必要的。

下面这个函数是读取CSV文件中指定的某几行数据:

 代码如下 复制代码

/**
 * csv_get_lines 读取CSV文件中的某几行数据
 * @param $csvfile csv文件路径
 * @param $lines 读取行数
 * @param $offset 起始行数
 * @return array
 * */
function csv_get_lines($csvfile, $lines, $offset = 0) {
    if(!$fp = fopen($csvfile, 'r')) {
     return false;
    }
    $i = $j = 0;
 while (false !== ($line = fgets($fp))) {
  if($i++ < $offset) {
   continue;
  }
  break;
 }
 $data = array();
 while(($j++ < $lines) && !feof($fp)) {
  $data[] = fgetcsv($fp);
 }
 fclose($fp);
    return $data;
}
调用方法:

 

$data = csv_get_lines('path/bigfile.csv', 10, 2000000);

print_r($data);

函数主要采用行定位的思路,通过跳过起始行数来实现文件指针定位。

至于数据如何入库本文不再详细讲述。

上述函数对500M以内的文件进行过测试,运行通畅,对于1GB的文件发现有点慢了,于是再接着找方法。

如何快速完整的操作大文件仍然还存在一些问题。

1、如何快速获取CSV大文件的总行数?

办法一:直接获取文件内容,使用换行符进行拆分得出总行数,这种办法对小文件可行,处理大文件时不可行;

办法二:使用fgets一行一行遍历,得出总行数,这种办法比办法一好一些,但大文件仍有超时的可能;

办法三:借助SplFileObject类,直接将指针定位到文件末尾,通过SplFileObject::key方法获取总行数,这种办法可行,且高效。

具体实现方法:

 代码如下 复制代码
$csv_file = 'path/bigfile.csv';
$spl_object = new SplFileObject($csv_file, 'rb');
$spl_object->seek(filesize($csv_file));
echo $spl_object->key();

2、如何快速获取CSV大文件的数据?

仍然使用PHP的SplFileObject类,通过seek方法实现快速定位。

 代码如下 复制代码
$csv_file = 'path/bigfile.csv';
$start = 100000;  // 从第100000行开始 www.111cn.net读取
$num = 100;    // 读取100行
$data = array();
$spl_object = new SplFileObject($csv_file, 'rb');
$spl_object->seek($start);
while ($num-- && !$spl_object->eof()) {
 $data[] = $spl_object->fgetcsv();
 $spl_object->next();
}
print_r($data);

 

综合上面两点,整理成一个csv文件读取的类:

 代码如下 复制代码

class CsvReader {
 private $csv_file;
 private $spl_object = null;
 private $error;
 
 public function __construct($csv_file = '') {
  if($csv_file && file_exists($csv_file)) {
   $this->csv_file = $csv_file;
  }
 }
 
 public function set_csv_file($csv_file) {
  if(!$csv_file || !file_exists($csv_file)) {
   $this->error = 'File invalid';
   return false;
  }
  $this->csv_file = $csv_file;
  $this->spl_object = null;
 }
 
 public function get_csv_file() {
  return $this->csv_file;
 }
 
 private function _file_valid($file = '') {
  $file = $file ? $file : $this->csv_file;
  if(!$file || !file_exists($file)) {
   return false;
  }
  if(!is_readable($file)) {
   return false;
  }
  return true;
 }
 
 private function _open_file() {
  if(!$this->_file_valid()) {
   $this->error = 'File invalid';
   return false;
  }
  if($this->spl_object == null) {
   $this->spl_object = new SplFileObject($this->csv_file, 'rb');
  }
  return true;
 }

 public function get_data($length = 0, $start = 0) {
  if(!$this->_open_file()) {
   return false;
  }
  $length = $length ? $length : $this->get_lines();
  $start = $start - 1;
  $start = ($start < 0) ? 0 : $start;
  $data = array();
  $this->spl_object->seek($start);
  while ($length-- && !$this->spl_object->eof()) {
   $data[] = $this->spl_object->fgetcsv();
   $this->spl_object->next();
  }
  return $data;
 }
 
 public function get_lines() {
  if(!$this->_open_file()) {
   return false;
  }
  $this->spl_object->seek(filesize($this->csv_file));
  return $this->spl_object->key();
 }
 
 public function get_error() {
  return $this->error;
 }
}

调用方法如下:

 代码如下 复制代码

include('CsvReader.class.php');

$csv_file = 'path/bigfile.csv';

$csvreader = new CsvReader($csv_file);

$line_number = $csvreader->get_lines();

$data = $csvreader->get_data(10);

 

echo $line_number, chr(10);

print_r($data);

 

其实,上述CsvReader类并不只针对CSV大文件,对于其他文本类型的大文件或超大文件同样可用,前提是将类中fgetcsv方法稍加改动为current即可。

 

利用php备份mysql数据库就是把数据生成.sql文件,这样就算是数据备份成功了,恢复时也可以直接读取再一条条执行即可,下面整理了一些备份例子大家有兴趣的可进来参考。

例子。

 

 代码如下 复制代码
<?php
// 备份数据库
$host = "localhost";
$user = "root"; //数据库账号
$password = ""; //数据库密码
$dbname = "mysql"; //数据库名称
// 这里的账号、密码、名称都是从页面传过来的
if (!mysql_connect($host, $user, $password)) // 连接mysql数据库
    {
        echo '数据库连接失败,请核对后再试';
    exit;
}
if (!mysql_select_db($dbname)) // 是否存在该数据库
    {
        echo '不存在数据库:' . $dbname . ',请核对后再试';
    exit;
}
mysql_query("set names 'utf8'");
$mysql = "set charset utf8;\r\n";
$q1 = mysql_query("show tables");
while ($t = mysql_fetch_array($q1))
{
    $table = $t[0];
    $q2 = mysql_query("show create table `$table`");
    $sql = mysql_fetch_array($q2);
    $mysql .= $sql['Create Table'] . ";\r\n";
    $q3 = mysql_query("select * from `$table`");
    while ($data = mysql_fetch_assoc($q3))
    {
        $keys = array_keys($data);
        $keys = array_map('addslashes', $keys);
        $keys = join('`,`', $keys);
        $keys = "`" . $keys . "`";
        $vals = array_values($data);
        $vals = array_map('addslashes', $vals);
        $vals = join("','", $vals);
        $vals = "'" . $vals . "'";
        $mysql .= "insert into `$table`($keys) values($vals);\r\n";
    }
}
 
$filename = $dbname . date('Ymjgi') . ".sql"; //存放路径,默认存放到项目最外层
$fp = fopen($filename, 'w');
fputs($fp, $mysql);
fclose($fp);
echo "数据备份成功";
 
?>


例子

 代码如下 复制代码

#!/usr/bin/php www.111cn.net
<?php
header('Content-Type:text/html;charset=utf-8');

define('BACK_PATH', dirname(__FILE__));

/**
为空数组就备份所有数据库
*/
$back_databases = array('learning','wp');

$mysql_host = 'localhost';

$mysql_user = 'root';

$mysql_passwd = 'root';

if($conn = mysql_connect($mysql_host, $mysql_user, $mysql_passwd)){
 
 $databases = array();
 
 mysql_select_db('mysql', $conn);
 
 $query  =mysql_query('show databases',$conn);
 
 while($row = mysql_fetch_array($query))
 {
  if(empty($row)) continue;
  
  $database = $row[0];
  
  if(!empty($back_databases) && !in_array($database, $back_databases)) continue;
    
  $sql_dir = BACK_PATH . "/{$database}.sql";
   
  $execs = "mysqldump --user={$mysql_user} --password={$mysql_passwd} {$database} > " . $sql_dir;
  
  system($execs);
  
  if(file_exists($sql_dir . '.gz')) {
     unlink($sql_dir . '.gz');
  }
    
  system('gzip ' . $sql_dir);
 }
}

例子

 代码如下 复制代码
<?php
$host="##mysql服务器地址##";
$user="##登录帐号##";
$password="##登录密码##";
$dbname="##数据库名##";
$filename="##备份文件路径##";
mysql_connect($host,$user,$password);
mysql_select_db($dbname);
$mysql.="CREATE DATABASE IF NOT EXISTS `".$dbname."`;\r\n";
$mysql.="USE `".$dbname."`;\r\n\r\n";
$q0=mysql_query("set names utf8");
$q1=mysql_query("show tables");
while($t=mysql_fetch_array($q1)){
  $table=$t[0];
  $mysql.="DROP TABLE IF EXISTS `".$table."`;\r\n";
  $q2=mysql_query("show create table `$table`");
  $sql=mysql_fetch_array($q2);
  $mysql.=$sql['Create Table'].";\r\n\r\n";
  $q3=mysql_query("select * from `$table`");
  while($data=mysql_fetch_assoc($q3)){
    $keys=array_keys($data);
    $keys=array_map('addslashes',$keys);
    $keys=join('`,`',$keys);
    $keys="`".$keys."`";
    $vals=array_values($data);
    $vals=array_map('addslashes',$vals);
    $vals=join("','",$vals);
    $vals="'".$vals."'";
    $mysql.="insert into `$table`($keys) values($vals);\r\n";
  }
  $mysql.="\r\n";
}
$fp = fopen($filename,'wb');
fputs($fp,$mysql);
fclose($fp);
include_once('lib/pclzip.lib.php');
$archive = new PclZip($filename.'.zip');
$v_list = $archive->create($filename);
if ($v_list == 0) {
   die("Error : ".$archive->errorInfo(true));
}
if(file_exists($filename)){
   unlink($filename);
}
echo "Mysql's backup successfully to ".$filename.".zip";
?>

Zip打包备份代码,几乎就是全抄demo,太方便了:

 代码如下 复制代码

 

<?PHP
include_once('lib/pclzip.lib.php');
$src="##源路径##";
$dest="##目标zip路径##";
$archive = new PclZip($dest);
$v_list = $archive->create($src);
if ($v_list == 0) {
   die("Error : ".$archive->errorInfo(true));
}else{
     print("Success");
}
?>

pclzip.lib.php这个压缩包文件大家百度去下载这里未提供。

在php连接mssql时查询出来的全部是问题了,这种问题我根据经验知道是编码问题,下面来给各位总结一下解决方法。

方法一,修改php.ini文件 (当然根据你页面情况来设置也可以是utf-8编码了。

 代码如下 复制代码

;mssql.charset = "ISO-8859-1"
mssql.charset = "GBK"

方法二,直接程序中转换

 代码如下 复制代码

iconv('GB2312','UTF-8',$data)

方法三,利用Ado连接在连接时设置编码

$conn = new COM(“ADODB.Connection”, NULL, CP_UTF8) or die(“Cannot start ADO”);  

例子

 代码如下 复制代码
•<html> 
•<head> 
•<meta http-equiv=“Content-Type” content=“text/html; charset=utf-8″> 
•</head> 
•<body> 
•<?php 
•//print(“The next line generates an error.www.111Cn.net<br>”); 
•//printaline(“PLEASE?”); 
•//print(“This will not be displayed due to the above error.”); 
•?> 
• 
•<?php 
• 
•$conn = new COM(“ADODB.Connection”, NULL, CP_UTF8) or die(“Cannot start ADO”);  
•//access 数据库的打开方式 
•//$conn->Open(“Provider=Microsoft.Jet.OLEDB.4.0; Data Source=$db”); 
•//$conn->Open(“DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=$db”); 
•$conn->Open(“Driver={SQL Server};Server={192.168.22.40};Database=sugarcrm_db;UID=sa;PWD=123456;”) ;  
•// 执行查询并输出数据 
•$rs = $conn->Execute(‘SELECT * FROM accounts’) or die (“error query”); 
•?> 
•<table border=“1″> 
•<tr><th>ID</th><th>Title</th> 
•</tr> 
•<?php 
•while (!$rs->EOF) { 
•  echo ‘<tr>’; 
•  echo ‘<td>’. $rs->Fields['id']->Value .‘</td>’; 
•  echo ‘<td>’. $rs->Fields['name']->Value .‘</td>’; 
•  echo ‘</tr>’; 
•  $rs->MoveNext(); 
•} 
•?> 
•</table> 
•<?php 
•// 释放资源 
•$rs->Close(); 
•$conn->Close(); 
•$rs = null; 
•$conn = null; 
• 
•?> 
•</body> 
•</html> 

总结

一是:数据库类型,其中包括,数据库,表,字段三处都要统一,可以检查一下
二是:文件的编码类型,你若用dw或editplus可以查看页面编码,不同需修改
三是:访问数据库时的设置既set NAMES utf8;
四是:浏览器显示方式,添加meta属性<meta charset=utf-8>

Excel中的日期,php读取之后,变成了类似25569这样的数字,而不是Excel中显示的1970-1-1字符形式。原来excel中的日期是个1900-1-1开始的数字格式。比如1900-1-1是1,1970-1-1是25569。

提供一个读取的函数:

 代码如下 复制代码

//excel日期转换函数
function excelTime($date, $time = false) {
 if(function_exists('GregorianToJD')){
  if (is_numeric( $date )) {
   $jd = GregorianToJD( 1, 1, 1970 );
   $gregorian = JDToGregorian( $jd + intval ( $date ) - 25569 );
   $date = explode( '/', $gregorian );
   $date_str = str_pad( $date [2], 4, '0', STR_PAD_LEFT )
      ."-". str_pad( $date [0], 2, '0', STR_PAD_LEFT )
      ."-". str_pad( $date [1], 2, '0', STR_PAD_LEFT )
      . ($time ? " 00:00:00" : '');
   return $date_str;
  }
 }else{
  $date=$date>25568?$date+1:25569;
  /*There was a bug if Converting date before 1-1-1970 (tstamp 0)*/
  $ofs=(70 * 365 + 17+2) * 86400;
  $date =  date("Y-m-d",($date * 86400) - $ofs).($time ? " 00:00:00" : '');
 }
 return $date;
}

[!--infotagslink--]

相关文章

  • C#连接SQL数据库和查询数据功能的操作技巧

    本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
  • php简单数据操作的实例

    最基础的对数据的增加删除修改操作实例,菜鸟们收了吧...2013-09-26
  • 解决Mybatis 大数据量的批量insert问题

    这篇文章主要介绍了解决Mybatis 大数据量的批量insert问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-09
  • Antd-vue Table组件添加Click事件,实现点击某行数据教程

    这篇文章主要介绍了Antd-vue Table组件添加Click事件,实现点击某行数据教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-11-17
  • 详解如何清理redis集群的所有数据

    这篇文章主要介绍了详解如何清理redis集群的所有数据,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-18
  • vue 获取到数据但却渲染不到页面上的解决方法

    这篇文章主要介绍了vue 获取到数据但却渲染不到页面上的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-19
  • js导出table数据到excel即导出为EXCEL文档的方法

    复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta ht...2013-10-13
  • php把读取xml 文档并转换成json数据代码

    在php中解析xml文档用专门的函数domdocument来处理,把json在php中也有相关的处理函数,我们要把数据xml 数据存到一个数据再用json_encode直接换成json数据就OK了。...2016-11-25
  • mybatis-plus 处理大数据插入太慢的解决

    这篇文章主要介绍了mybatis-plus 处理大数据插入太慢的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-12-18
  • postgresql数据添加两个字段联合唯一的操作

    这篇文章主要介绍了postgresql数据添加两个字段联合唯一的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-04
  • Vue生命周期activated之返回上一页不重新请求数据操作

    这篇文章主要介绍了Vue生命周期activated之返回上一页不重新请求数据操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-26
  • 解决vue watch数据的方法被调用了两次的问题

    这篇文章主要介绍了解决vue watch数据的方法被调用了两次的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-11-07
  • c# socket网络编程接收发送数据示例代码

    这篇文章主要介绍了c# socket网络编程,server端接收,client端发送数据,大家参考使用吧...2020-06-25
  • vue 数据(data)赋值问题的解决方案

    这篇文章主要介绍了vue 数据(data)赋值问题的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-29
  • Python3 常用数据标准化方法详解

    这篇文章主要介绍了Python3 常用数据标准化方法详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-24
  • C# 导出Excel的6种简单方法实现

    C# 导出 Excel 的6种简单方法:数据表导出到 Excel,对象集合导出到 Excel,数据库导出到 Excel,微软网格控件导出到 Excel,数组导出到 Excel,CSV 导出到 Excel,你都会了吗?需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
  • node.js从数据库获取数据

    这篇文章主要为大家详细介绍了node.js从数据库获取数据的具体代码,nodejs可以获取具体某张数据表信息,感兴趣的朋友可以参考一下...2016-05-09
  • 分享MYSQL插入数据时忽略重复数据的方法

    使用下以两种方法时必须把字段设为”主键(PRIMARY KEY”或”唯一约束(UNIQUE)”。1:使用REPLACE INTO (此种方法是利用替换的方法,有点似类于先删除再插入) 复制代码 代码如下:REPLACE INTO Syntax REPLACE [LOW_PRIO...2013-10-04
  • PostgreSQL 恢复误删数据的操作

    这篇文章主要介绍了PostgreSQL 恢复误删数据的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-18
  • C#实现窗体间传递数据实例

    这篇文章主要介绍了C#实现窗体间传递数据实例,需要的朋友可以参考下...2020-06-25