Преобразование таблицы HTML в CSV автоматически с использованием PHP?

Мне просто нужно преобразовать эту таблицу html автоматически в csv с помощью PHP. Может ли кто-нибудь представить, как это сделать? Благодарю.

$table = '<table border="1"> <tr> <th>Header 1</th> <th>Header 2</th> </tr> <tr> <td>row 1, cell 1</td> <td>row 1, cell 2</td> </tr> <tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> </tr> </table>'; 

Ребята, мне просто нужно $ table преобразовать только в .csv- файл, который может быть автоматически сгенерирован с использованием некоторой функции PHP. Мы можем определить путь для этого файла csv для / test / home / path_to_csv

Вы можете использовать str_get_html http://simplehtmldom.sourceforge.net/

 include "simple_html_dom.php"; $table = '<table border="1"> <tr> <th>Header 1</th> <th>Header 2</th> </tr> <tr> <td>row 1, cell 1</td> <td>row 1, cell 2</td> </tr> <tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> </tr> </table>'; $html = str_get_html($table); header('Content-type: application/ms-excel'); header('Content-Disposition: attachment; filename=sample.csv'); $fp = fopen("php://output", "w"); foreach($html->find('tr') as $element) { $td = array(); foreach( $element->find('th') as $row) { $td [] = $row->plaintext; } fputcsv($fp, $td); $td = array(); foreach( $element->find('td') as $row) { $td [] = $row->plaintext; } fputcsv($fp, $td); } fclose($fp); 

Вы можете использовать эту функцию в отдельном файле js:

 function exportTableToCSV($table, filename) { var $rows = $table.find('tr:has(td)'), // Temporary delimiter characters unlikely to be typed by keyboard // This is to avoid accidentally splitting the actual contents tmpColDelim = String.fromCharCode(11), // vertical tab character tmpRowDelim = String.fromCharCode(0), // null character // actual delimiter characters for CSV format colDelim = '","', rowDelim = '"\r\n"', // Grab text from table into CSV formatted string csv = '"' + $rows.map(function (i, row) { var $row = $(row), $cols = $row.find('td'); return $cols.map(function (j, col) { var $col = $(col), text = $col.text(); return text.replace('"', '""'); // escape double quotes }).get().join(tmpColDelim); }).get().join(tmpRowDelim) .split(tmpRowDelim).join(rowDelim) .split(tmpColDelim).join(colDelim) + '"', // Data URI csvData = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csv); $(this) .attr({ 'download': filename, 'href': csvData, 'target': '_blank' }); } 

Теперь, чтобы инициировать эту функцию, вы можете использовать:

 $('.getfile').click( function() { exportTableToCSV.apply(this, [$('#thetable'), 'filename.csv']); }); 

где «getfile» должен быть классом, назначенным кнопке, где вы хотите добавить вызов к действию. (При нажатии этой кнопки появится всплывающее окно загрузки), а «таблица» должна быть идентификатором, присвоенным таблице, которую вы хотите загрузить.

Вы также можете изменить имя пользовательского файла для загрузки в код.

Чтобы расширить принятый ответ, я сделал это, что позволяет мне игнорировать столбцы по имени класса, а также имеет дело с пустыми строками / столбцами.

Вы можете использовать str_get_html http://simplehtmldom.sourceforge.net/ . Просто включите его и прочь! 🙂

 $html = str_get_html($html); // give this your HTML string header('Content-type: application/ms-excel'); header('Content-Disposition: attachment; filename=sample.csv'); $fp = fopen("php://output", "w"); foreach($html->find('tr') as $element) { $td = array(); foreach( $element->find('th') as $row) { if (strpos(trim($row->class), 'actions') === false && strpos(trim($row->class), 'checker') === false) { $td [] = $row->plaintext; } } if (!empty($td)) { fputcsv($fp, $td); } $td = array(); foreach( $element->find('td') as $row) { if (strpos(trim($row->class), 'actions') === false && strpos(trim($row->class), 'checker') === false) { $td [] = $row->plaintext; } } if (!empty($td)) { fputcsv($fp, $td); } } fclose($fp); exit; 

Вы можете сделать это с помощью массивов и регулярных выражений … См. Ниже

 $csv = array(); preg_match('/<table(>| [^>]*>)(.*?)<\/table( |>)/is',$table,$b); $table = $b[2]; preg_match_all('/<tr(>| [^>]*>)(.*?)<\/tr( |>)/is',$table,$b); $rows = $b[2]; foreach ($rows as $row) { //cycle through each row if(preg_match('/<th(>| [^>]*>)(.*?)<\/th( |>)/is',$row)) { //match for table headers preg_match_all('/<th(>| [^>]*>)(.*?)<\/th( |>)/is',$row,$b); $csv[] = strip_tags(implode(',',$b[2])); } elseif(preg_match('/<td(>| [^>]*>)(.*?)<\/td( |>)/is',$row)) { //match for table cells preg_match_all('/<td(>| [^>]*>)(.*?)<\/td( |>)/is',$row,$b); $csv[] = strip_tags(implode(',',$b[2])); } } $csv = implode("\n", $csv); var_dump($csv); 

Затем вы можете использовать file_put_contents () для записи строки csv в файл.

Мне никогда не приходилось делать это раньше, но я нашел этот учебник, который включает в себя исходные файлы, а также короткий и очень простой:

http://davidvielmetter.com/tricks/howto-convert-an-html-table-to-csv-using-php/

Если кто-то использует ответ Бабы, но почесывает голову над добавлением лишних белых пространств, это будет работать:

 include "simple_html_dom.php"; $table = '<table border="1"> <tr> <th>Header 1</th> <th>Header 2</th> </tr> <tr> <td>row 1, cell 1</td> <td>row 1, cell 2</td> </tr> <tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> </tr> </table>'; $html = str_get_html($table); $fileName="export.csv"; header('Content-type: application/ms-excel'); header("Content-Disposition: attachment; filename=$fileName"); $fp = fopen("php://output", "w"); $csvString=""; $html = str_get_html(trim($table)); foreach($html->find('tr') as $element) { $td = array(); foreach( $element->find('th') as $row) { $row->plaintext="\"$row->plaintext\""; $td [] = $row->plaintext; } $td=array_filter($td); $csvString.=implode(",", $td); $td = array(); foreach( $element->find('td') as $row) { $row->plaintext="\"$row->plaintext\""; $td [] = $row->plaintext; } $td=array_filter($td); $csvString.=implode(",", $td)."\n"; } echo $csvString; fclose($fp); exit; 

}

Я адаптировал простой класс на основе кода, найденного в этом потоке, который теперь обрабатывает colspan и rowspan . Не тестировалось сильно, и я уверен, что он может быть оптимизирован.

Применение:

 require_once('table2csv.php'); $table = '<table border="1"> <tr> <th colspan=2>Header 1</th> </tr> <tr> <td>row 1, cell 1</td> <td>row 1, cell 2</td> </tr> <tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> </tr> <tr> <td rowspan=2>top left row</td> <td>top right row</td> </tr> <tr> <td>bottom right</td> </tr> </table>'; table2csv($table,"sample.csv",true); 

table2csv.php

 <?php //download @ http://simplehtmldom.sourceforge.net/ require_once('simple_html_dom.php'); $repeatContentIntoSpannedCells = false; //-------------------------------------------------------------------------------------------------------------------- function table2csv($rawHTML,$filename,$repeatContent) { //get rid of sups - they mess up the wmus for ($i=1; $i <= 20; $i++) { $rawHTML = str_replace("<sup>".$i."</sup>", "", $rawHTML); } global $repeatContentIntoSpannedCells; $html = str_get_html(trim($rawHTML)); $repeatContentIntoSpannedCells = $repeatContent; //we need to pre-initialize the array based on the size of the table (how many rows vs how many columns) //counting rows is easy $rowCount = count($html->find('tr')); //column counting is a bit trickier, we have to iterate through the rows and basically pull out the max found $colCount = 0; foreach ($html->find('tr') as $element) { $tempColCount = 0; foreach ($element->find('th') as $cell) { $tempColCount++; } if ($tempColCount == 0) { foreach ($element->find('td') as $cell) { $tempColCount++; } } if ($tempColCount > $colCount) $colCount = $tempColCount; } $mdTable = array(); for ($i=0; $i < $rowCount; $i++) { array_push($mdTable, array_fill(0, $colCount, NULL)); } //////////done predefining array $rowPos = 0; $fp = fopen($filename, "w"); foreach ($html->find('tr') as $element) { $colPos = 0; foreach ($element->find('th') as $cell) { if (strpos(trim($cell->class), 'actions') === false && strpos(trim($cell->class), 'checker') === false) { parseCell($cell,$mdTable,$rowPos,$colPos); } $colPos++; } foreach ($element->find('td') as $cell) { if (strpos(trim($cell->class), 'actions') === false && strpos(trim($cell->class), 'checker') === false) { parseCell($cell,$mdTable,$rowPos,$colPos); } $colPos++; } $rowPos++; } foreach ($mdTable as $key => $row) { //clean the data array_walk($row, "cleanCell"); fputcsv($fp, $row); } } function cleanCell(&$contents,$key) { $contents = trim($contents); //get rid of pesky &nbsp's (aka: non-breaking spaces) $contents = trim($contents,chr(0xC2).chr(0xA0)); $contents = str_replace("&nbsp;", "", $contents); } function parseCell(&$cell,&$mdTable,&$rowPos,&$colPos) { global $repeatContentIntoSpannedCells; //if data has already been set into the cell, skip it while (isset($mdTable[$rowPos][$colPos])) { $colPos++; } $mdTable[$rowPos][$colPos] = $cell->plaintext; if (isset($cell->rowspan)) { for ($i=1; $i <= ($cell->rowspan)-1; $i++) { $mdTable[$rowPos+$i][$colPos] = ($repeatContentIntoSpannedCells ? $cell->plaintext : ""); } } if (isset($cell->colspan)) { for ($i=1; $i <= ($cell->colspan)-1; $i++) { $colPos++; $mdTable[$rowPos][$colPos] = ($repeatContentIntoSpannedCells ? $cell->plaintext : ""); } } } ?> 

Ответ Бабы содержит дополнительное пространство. Итак, я обновил код до этого:

 include "simple_html_dom.php"; $table = '<table border="1"> <tr> <th>Header 1</th> <th>Header 2</th> </tr> <tr> <td>row 1, cell 1</td> <td>row 1, cell 2</td> </tr> <tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> </tr> </table>'; $html = str_get_html($table); header('Content-type: application/ms-excel'); header('Content-Disposition: attachment; filename=sample.csv'); $fp = fopen("php://output", "w"); foreach($html->find('tr') as $element) { $td = array(); foreach( $element->find('th') as $row) { $td [] = $row->plaintext; } foreach( $element->find('td') as $row) { $td [] = $row->plaintext; } fputcsv($fp, $td); } fclose($fp);