Предположим, что у нас есть такая функция, которая принимает PDOStatement (любой запрос) и автоматически генерирует файл excel (используя библиотеку PHPExcel):Конвертировать целое число в столбец Excel (комбинация букв или букв) - полный пример PHP, модульный тест и объяснение
/**
* Create an Excel file from an opened PDOStatement. Return the path to access the Excel file
* or an empty string if we were not able to create the Excel File
*
*
* @param $errorMessage String to return the error message.
* @param $source PDOStatement containing the data to export to Excel.
* @param $rows Int Use to return the number of rows exported (the header row isn't counted).
* @param $name String name to give to the Excel file (no need to specify the extension).
* @param $columnName (optional) String Array used for the name of the row in the Excel file.
*
* @return String
*/
public static function createExcelFromRS(&$errorMessage, PDOStatement &$source, &$rows , $name, array $columnName = array()){
$errorMessage = "";
$name = self::validateFileExtention($name, "xlsx");
$path = realpath(dirname(__FILE__)) . '/Archive/' . $name;
$rows = 0;
$totalCols = 0;
$excel = new PHPExcel();
$writer = PHPExcel_IOFactory::createWriter($excel, "Excel2007");
$sheet = $excel->getActiveSheet();
$sheet->setTitle($name);
while ($row = $source->fetch(PDO::FETCH_ASSOC)){
if ($rows === 0){
$columnName = self::validateColumnNameArray($columnName, $row);
$totalCols = count($row);
$sheet->getStyle('A1:' . self::convertNumberToExcelCol($totalCols) . '1')->getFont()->setBold(true)->setSize(12);
for ($column = 1; $column <= $totalCols; $column++){
$sheet->getCell(self::convertNumberToExcelCol($column) . '1')->setValue($columnName[$column - 1]);
$sheet->getColumnDimension(self::convertNumberToExcelCol($column))->setAutoSize(true);
}
$rows = 1;
}
$rows++;
$column = 1;
foreach ($row as $field){
$sheet->getCell(self::convertNumberToExcelCol($column) . $rows)->setValue($field);
$column++;
}
}
$writer->save($path);
unset($sheet, $writer, $excel);
if ($rows < 1){
if (is_file($path)){
unlink($path);
}
$errorMessage =str_replace("[TYPE]", "EXCEL", GeneralDbManager::getInstance()->getErrorMessage('NO_DATA_TO_EXPORT_FILE_ERR', 'There is no data to export to the [TYPE] file.'));
}
elseif(!is_file($path)){
$errorMessage = str_replace(array("[TYPE]", "[NAME]"), array("EXCEL", $name), GeneralDbManager::getInstance()->getErrorMessage('EXPORT_NO_CREATED_FILE_ERR', 'We were not able to create the [TYPE] file: [NAME].'));
}
else{
$rows --;
}
return (empty($errorMessage) ? $path : "");
}
и мы хотим, чтобы преобразовать целое значение в столбце Excel с помощью функции convertNumberToExcelCol
.
Давайте сначала объясним этот метод для создания файла excel, и следующее сообщение объяснит алгоритм, чтобы получить столбец.
Методы, принимает в качестве параметра:
- ErrorMessage: использовать для возврата сообщения об ошибке,
- источника: содержат данные, чтобы подтолкнуть к Ехчел
- Rows: Использование для возврата количества экспортированных строк данных
- имя: Название t o предоставить файлу excel
- columnName: необязательный массив, используемый с именем для чтения человеком (или переводом). Если этот параметр опущен, метод использует имя поля из запроса.
Первые строки предназначены для инициализации параметров (PHP использует свободную типизацию, поэтому мы должны быть осторожны с параметрами).
Эта функция убедитесь, что имя есть действительное имя/расширение:
/**
* Validate that the file $name has the proper file $extension
* and return the fixed name with the proper extension
*
* Note: No modification will be made if the extension is not a string or is empty
*
* @param $name String file name with or without extension
* @param $extension String example: csv, xls
*
* @return String
*/
public static function validateFileExtention($name, $extension){
if (is_string($extension)){
$extension = "." . str_replace(".", "", $extension);
if (strlen($extension) > 1){
if (!is_string($name) or empty($name) or strpos($name, ".") === 0){
$name = "my_file" . $extension;
}
elseif(strpos(strtolower($name), $extension) === false){
if (strrpos($name, ".") === false){
$name .= $extension;
}
else{
if (substr_count($name, ".") > 1){
$name = str_replace(".", "", $name) . $extension;
}
else{
$name = str_replace(substr($name, strrpos($name, ".")), $extension, $name);
}
}
}
}
}
return $name;
}
Затем мы открываем подключение к файлу Excel:
$excel = new PHPExcel();
$writer = PHPExcel_IOFactory::createWriter($excel, "Excel2007");
$sheet = $excel->getActiveSheet();
$sheet->setTitle($name);
Эта функция гарантирует, что имя столбца массив имеет ту же длину, что и количество полей в массиве строк.
/**
* Take the array containing the $columnName for data export (CSV, Excel) and make sure
* that it is the number of entry as there are fields in $row.
*
* If column name are missing, we will use the column name used in the query.
*
* Return the merged array
*
* @param $columnName Array containing the column names
* @param $row Array produce by fetch(PDO::FETCH_ASSOC).
*
* @return Array ($columnName)
*/
private static function validateColumnNameArray(array &$columnName, array &$row){
$buffer = array();
$colPDO = count($row);
$count = count($columnName);
if ($count < $colPDO){
foreach ($row as $key => $value){
$buffer[] = $key;
}
for($index = $count; $index < $colPDO; $index++){
$columnName[] = $buffer[$index];
}
}
unset($buffer);
return $columnName;
}
Оба validateFileExtention
и validateColumnNameArray
предназначены для общего кода с функцией создания CSV:
/**
* Create a CSV file from an opened PDOStatement. Return the path to access the CSV file
* or an empty string if we were not able to create the CSV File
*
*
* @param $errorMessage String to return the error message.
* @param $source PDOStatement containing the data to export to CSV
* @param $rows Int Use to return the number of rows exported (the header row isn't counted).
* @param $name String name to give to the CSV file (no need to specify the extension).
* @param $columnName (optional) String Array used for the name of the row in the CSV file.
*
* @return String
*/
public static function createCSVFromRS(&$errorMessage, PDOStatement &$source, &$rows , $name, array $columnName = array()){
$errorMessage = "";
$name = self::validateFileExtention($name, "csv");
$path = realpath(dirname(__FILE__)) . '/Archive/' . $name;
$rows = 0;
$file = fopen($path, "w");
while ($row = $source->fetch(PDO::FETCH_ASSOC)){
if ($rows === 0){
fputcsv($file, array_map('utf8_decode',self::validateColumnNameArray($columnName, $row)));
}
fputcsv($file, array_map('utf8_decode',array_values($row)));
$rows++;
}
fclose($file);
if ($rows < 1){
if (is_file($path)){
unlink($path);
}
$errorMessage =str_replace("[TYPE]", "CSV", GeneralDbManager::getInstance()->getErrorMessage('NO_DATA_TO_EXPORT_FILE_ERR', 'There is no data to export to the [TYPE] file.'));
}
elseif(!is_file($path)){
$errorMessage = str_replace(array("[TYPE]", "[NAME]"), array("CSV", $name), GeneralDbManager::getInstance()->getErrorMessage('EXPORT_NO_CREATED_FILE_ERR', 'We were not able to create the [TYPE] file: [NAME].'));
}
return (empty($errorMessage) ? $path : "");
}
Если это первая строка добавляется в файл Excel, то мы устанавливаем основные форматирования:
if ($rows === 0){
$columnName = self::validateColumnNameArray($columnName, $row);
$totalCols = count($row);
$sheet->getStyle('A1:' . self::convertNumberToExcelCol($totalCols) . '1')->getFont()->setBold(true)->setSize(12);
for ($column = 1; $column <= $totalCols; $column++){
$sheet->getCell(self::convertNumberToExcelCol($column) . '1')->setValue($columnName[$column - 1]);
$sheet->getColumnDimension(self::convertNumberToExcelCol($column))->setAutoSize(true);
}
$rows = 1;
}
С помощью метода getStyle мы устанавливаем строку заголовка жирным шрифтом и размером 12.
Метод getCOlumnDimension используется для установки автосохранения, поэтому пользователю не нужно изменять размер самого столбца при открытии файла.
Остальная часть цикла - перенос данных из массива строк в файл excel.
После циклов мы закрываем соединение и отключим использование переменной для управления Excel.
Затем идет управление ошибками:
if ($rows < 1){
if (is_file($path)){
unlink($path);
}
$errorMessage =str_replace("[TYPE]", "EXCEL", GeneralDbManager::getInstance()->getErrorMessage('NO_DATA_TO_EXPORT_FILE_ERR', 'There is no data to export to the [TYPE] file.'));
}
elseif(!is_file($path)){
$errorMessage = str_replace(array("[TYPE]", "[NAME]"), array("EXCEL", $name), GeneralDbManager::getInstance()->getErrorMessage('EXPORT_NO_CREATED_FILE_ERR', 'We were not able to create the [TYPE] file: [NAME].'));
}
else{
$rows --;
}
Сообщения хранится в базе данных, поэтому мы можем предложить переведенное сообщение пользователя. Я использую общие теги [TYPE] и [NAME] в своем сообщении, которое я заменяю на соответствующий тип файла и имя файла.
Это позволяет мне повторно использовать это общее сообщение как в моем файле excel, так и в CSV (или независимо от того, какой файл) я создаю.
Если созданный файл пуст, я его удаляю. Эта операция является необязательной, но мне нравится очищать неиспользуемый файл с диска, как только я закончил с ним.
Другой способ обойти это использовать функцию, чтобы очистить каталог хранения:
/**
* Clear all the archives (zip) files in the archive folder.
*/
public static function emptyArchiveFolder(){
$handle = NULL;
$path = realpath(dirname(__FILE__)) . '/Archive/';
if (is_dir($path) and $handle = opendir($path)) {
while (false !== ($entry = readdir($handle))) {
$file = $path . $entry;
if (is_file($file)){
unlink($file);
}
}
unset($handle);
}
}
Я лично только с помощью этой методики, когда я делаю процедуру автоматического резервного копирования моего исходного файла и базы данных в полночь , Запуск в течение дня увеличивает вероятность удаления файлов другим пользователем.
Вот почему я рассматриваю лучшую практику для удаления файлов, как только они будут отправлены пользователю через браузер, и оставьте методы очистки только для целей обслуживания.
Если ошибок нет, я уменьшаю количество строк на единицу, так как не хочу подсчитывать строку заголовка. Эта строка может быть удалена, если вы рассматриваете строку заголовка как строку данных.
Наконец методы возвращают путь для доступа к вновь созданному файлу:
return (empty($errorMessage) ? $path : "");
, но только если не было никакой ошибки. Итак, если функция возвращает пустую строку, это означает, что произошла ошибка.
PHP, будучи свободным, может возвращать все, включая логическое или даже сообщение об ошибке, но я предпочитаю всегда возвращать один и тот же тип данных для цели постоянства. Мои личные любимые методы - это логические значения возврата и переменная сообщения об ошибке, переданная по ссылке. Так что я могу использовать такой код:
$errorMessage = "";
if ($_SESSION["adminAccount"]->updateAccountInfo($errorMessage,
(isset($_POST['FIRST_NAME_TEXT']) ? $_POST['FIRST_NAME_TEXT'] : $_SESSION["adminAccount"]->getFirstName()),
(isset($_POST['LAST_NAME_TEXT']) ? $_POST['LAST_NAME_TEXT'] : $_SESSION["adminAccount"]->getLastName()),
(isset($_POST['EMAIL_TEXT']) ? $_POST['EMAIL_TEXT'] : $_SESSION["adminAccount"]->getEmail()))){
PageManager::displaySuccessMessage("Your account information were saved with success.", "USER_ACCOUNT_INFORMATION_SAVED");
}
else{
PageManager::displayErrorMessage($errorMessage);
}
Таким образом, ошибка управляется изнутри методом класса, а сообщение успеха можно регулировать базу на контекст просмотра. Значение логического возврата используется для определения того, нужно ли отображать сообщение об ошибке или сообщение об успешном завершении.
Примечание: Единичный тест будет включен в мой ответ.
Джонатан Родитель-Левек из Монреаля
Я даю полное кодирование для автоматического создания файла csv и файла excel. Включите объяснение, как написать сложный алгоритм для преобразования значения числа в столбце excel. Подтвердите все, выполнив единичный тест. Программирование на 12 часов, 3 объяснения, и людям это не нравится. Сумасшедший мир, хе ... –