
CRM和数据平台
PHP 和 MySQL:将查询导出到制表符分隔文件或 CSV 文件
这个周末,我想建一个 PHP 可以备份任何内容的页面 MySQL的 查询或表放入制表符分隔文件中。 网上的大多数示例都对列进行了硬编码。
就我而言,我希望列是动态的,因此我必须首先循环遍历所有表字段名称以构建具有列名称的标题行,然后循环遍历剩余数据行的所有记录。 我还设置了标头,以便浏览器将以文件类型 (txt) 启动文件下载,并带有文件日期和时间戳的名称。
在 PHP 中从 MySQL 制表符分隔导出
<?php
$today = date("YmdHi");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$today."_Backup.txt\"");
$conn = new mysqli("hostname", "username", "password", "database_name"); // Replace with your database credentials
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$query = "SELECT * FROM `mytable` ORDER BY `myorder`";
$result = $conn->query($query);
if ($result->num_rows > 0) {
$fields = $result->fetch_fields();
// Prepare the header row
$header = [];
foreach ($fields as $field) {
$header[] = $field->name;
}
$data = implode("\t", $header) . "\n";
// Fetch and process the data rows
while ($row = $result->fetch_assoc()) {
$rowValues = [];
foreach ($fields as $field) {
$rowValues[] = $row[$field->name];
}
$data .= implode("\t", $rowValues) . "\n";
}
// Output the data
echo $data;
} else {
echo "No data found";
}
// Close the database connection
$conn->close();
?>
让我们逐步浏览一下代码,并对每个部分进行解释:
<?php
// Get the current date and time in a specific format
$today = date("YmdHi");
// Set HTTP headers for file download
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$today."_Backup.txt\"");
// Create a MySQL database connection
$conn = new mysqli("hostname", "username", "password", "database_name"); // Replace with your database credentials
// Check if the database connection was successful
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
- 我们以“YmdHi”格式生成当前日期和时间并将其存储在
$today
变量。 - HTTP 标头设置为指定应将内容视为八位字节流(二进制数据)并触发具有指定文件名的文件下载。
- 使用该扩展,我们创建一个 MySQL 数据库连接,用您的实际数据库凭据替换占位符。
- 我们检查数据库连接是否成功。 如果出现错误,我们将终止脚本并显示错误消息。
// Define the SQL query to select data from the `mytable` table
$query = "SELECT * FROM `mytable` ORDER BY `myorder`";
// Execute the SQL query
$result = $conn->query($query);
// Check if there are any rows returned
if ($result->num_rows > 0) {
// Fetch the field (column) names
$fields = $result->fetch_fields();
// Prepare the header row for the export file
$header = [];
foreach ($fields as $field) {
$header[] = $field->name;
}
$data = implode("\t", $header) . "\n";
- 我们定义 SQL 查询来选择所有数据
mytable
表,按顺序排序myorder
列。 - 执行查询,并将结果存储在
$result
变量。 - 我们通过检查是否有任何行返回
num_rows
结果对象的属性。 - 我们使用
fetch_fields()
检索字段(列)名称并将它们存储在$fields
数组。 - 导出文件的标题行是通过循环字段名称并将它们与制表符连接起来准备的。
// Fetch and process the data rows
while ($row = $result->fetch_assoc()) {
$rowValues = [];
foreach ($fields as $field) {
$rowValues[] = $row[$field->name];
}
$data .= implode("\t", $rowValues) . "\n";
}
- 我们使用一个
while
循环从结果集中获取每个数据行fetch_assoc()
. - 在循环内,我们通过迭代字段并收集相应的数据来准备每行的值。
- 每行的值都用制表符连接起来以创建制表符分隔的行,并将该行添加到
$data
变量。
// Output the data to the browser
echo $data;
} else {
// If no data is found, display a message
echo "No data found";
}
// Close the MySQL database connection
$conn->close();
?>
- 如果找到数据(检查
num_rows
),我们回显连接的数据,这是导出文件的内容。 这会触发用户浏览器中的文件下载。 - 如果未找到数据,我们会显示一条消息,指示没有可用数据。
- 我们使用以下命令关闭 MySQL 数据库连接
$conn->close()
以释放资源。
此代码有效地将数据从 MySQL 数据库表导出到制表符分隔的文本文件中,并处理各种情况,例如数据库连接错误和空结果集。
在 PHP 中从 MySQL 导出逗号分隔值
我可以修改代码以将数据导出为 CSV 文件。 以下是针对 CSV 导出进行更新的代码:
<?php
// Get the current date and time in a specific format
$today = date("YmdHi");
// Set HTTP headers for file download
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=\"".$today."_Backup.csv\"");
// Create a MySQL database connection
$conn = new mysqli("hostname", "username", "password", "database_name"); // Replace with your database credentials
// Check if the database connection was successful
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Define the SQL query to select data from the `mytable` table
$query = "SELECT * FROM `mytable` ORDER BY `myorder`";
// Execute the SQL query
$result = $conn->query($query);
// Check if there are any rows returned
if ($result->num_rows > 0) {
// Prepare the output file handle for writing
$output = fopen('php://output', 'w');
// Fetch and process the data rows
while ($row = $result->fetch_assoc()) {
// Output each row as a CSV line
fputcsv($output, $row);
}
// Close the output file handle
fclose($output);
} else {
// If no data is found, display a message
echo "No data found";
}
// Close the MySQL database connection
$conn->close();
?>
在这个修改后的代码中:
- HTTP 响应的标头已更新以指定
text/csv
内容类型,文件名具有“.csv”扩展名。 - 我们不使用手动创建 CSV 内容,而是使用
fputcsv
函数将 MySQL 结果集中的每一行输出为 CSV 行。 此函数为您处理 CSV 格式,包括处理特殊字符以及在必要时用双引号将字段括起来。 - 我们使用打开输出文件句柄
fopen
以“php://output”作为文件名。 这允许我们直接写入 HTTP 响应输出流。 - 该代码的结构可以有效地处理 CSV 导出,并在完成后关闭文件句柄。
此代码将从 MySQL 表中将数据导出为 CSV 文件,使用户可以轻松在 Excel 等电子表格应用程序中打开和使用。 不要忘记用您自己的数据库凭据替换数据库凭据。
你不能这样做:
SELECT `mytable` order by `myorder`
INTO OUTFILE '/tmp/Backup.txt'
FIELDS TERMINATED BY '\t'
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
?
我想你可以!
在这种情况下,我实际上是在 Web 应用程序中构建“备份”链接,因此我需要 PHP 功能。 但是,我从来不知道您也可以直接从 MySQL 语句写入文件。 很酷!
谢谢!
如果 MySQL 服务器在远程机器上,你的方式当然是最好的方式,因为它可能无法写入运行 PHP 的机器🙂
很高兴指出其他方向和新事物🙂
很棒的帖子。 您知道将制表符分隔文件(就像您刚刚创建的文件)导入/恢复回 mysql 数据库的简单、免费/开源方法吗?
错误... mysqlimport?
mysqlimport database_name --local backup.txt
或者使用 SQL 命令:
LOAD DATA LOCAL INFILE 'backup.txt' INTO TABLE `my_table` FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n'
使用 mysqlimport,文件名必须与表名匹配(只是需要注意的事情)
诺亚,我将在一周内用 PHP 构建那个! Bloid 是一个 MySQL 怪物! 感谢所有的投入!!!
我刚刚失去了 6 个多小时的生命,试图弄清楚为什么 Internet Explorer 6/7 应用文件类型“html”并且不接受我在标题中指定的自定义文件名......并且也不允许保存文件......当试图让用户下载以与上述类似方式创建的文本文件。
我使用的是 HTTPS,而 IE 不缓存这些文件。
我在 Brandon K 的评论中找到了解决方案 http://uk.php.net/header.
他说:
-
我刚刚失去了六个小时的生命,试图使用以下方法通过 PHP 将 PDF 文件发送到 Internet Explorer 6:
使用 SSL 时,Internet Explorer 将提示打开/保存对话框,但随后会显示“文件当前不可用或找不到。 请稍后再试。” 经过大量搜索后,我发现了以下 MSKB 文章,标题为“通过 SSL 下载 Internet Explorer 文件不适用于缓存控制标头”(KBID:323308)
PHP.INI 默认使用一个设置: session.cache_limiter = nocache 修改 Content-Cache 和 Pragma 标头以包含“nocache”选项。 您可以通过在 PHP.INI 中将“nocache”更改为“public”或“private”来消除 IE 错误——这将更改 Content-Cache 标头并完全删除 Pragma 标头。 如果您不能或不想修改 PHP.INI 以进行站点范围的修复,您可以发送以下两个标头来覆盖默认值:
您仍然需要设置上面列出的内容标题才能使其正常工作。 请注意,此问题仅影响 Internet Explorer,而 Firefox 不会出现这种有缺陷的行为。
-
好吧..至少他只损失了6个小时……
这很好用。 但是,我只是将所有内容放在一条用空格分隔的行上。 我正在尝试修改它以在单独的行上打印所有内容,如下所示:
列1_名称
字段1_值
列2_名称
字段1_值
列3_名称
字段1_值
列1_名称
字段2_值
列2_名称
字段2_值
列3_名称
字段2_值
例如:
名字
Mike
活动地点
工作
联系电话
1
名字
起诉
活动地点
首页
联系电话
2
名字
John
活动地点
旅行用品
联系电话
10
等等。 这个脚本可以修改吗?
谢谢!
当然可以。
尝试这样的事情:
SELECT * from MyTableName INTO OUTFILE 'MyTableName_MySQL-TAB-DELIMITED-29JUN08.txt' FIELDS TERMINATED BY '\n' LINES TERMINATED BY '\n';
如果您想在记录组之间使用双空格(两个空行),只需说“LINES TERMINATED BY '\n\n';” 反而。
“FIELDS TERMINATED BY '\n'”部分是在每条记录之后放置换行符,而不是制表符。 选项卡将改为 '\t'。
马拉纳莎!
这绝对是一篇很棒的帖子,我试过了,效果很好,唯一的问题是我的 txt 文件在标题上方有一个额外的行,并且一些结果被分成 2 行,这可能是由于我拥有的数据在我的数据库中不知道,但这对构建提要有很大帮助……
Douglas Karr 你的代码真的很震撼! 如果您只需要文本文件格式的输出,它特别有用。 非常感谢! 来自菲律宾队!
嘿! 这里有没有人可以给我一个关于使用我的 php 作为前端将文本文件导入我的数据库(phpmyAdmin)的提示。 我有一个关于下载文件并打开它的想法,我的问题是如何获得行结果以及如何将其插入到我的表中,谢谢
请有人告诉我如何删除标头标题上方的http标头行