PHPSpreadsheet 사용한 엑셀 업로드 (composer 없이) 정보
PHPSpreadsheet 사용한 엑셀 업로드 (composer 없이)첨부파일
본문
안녕하세요.
서버를 PHP8.0 + MySQL 8.0.27 + Apache 2.4.53 + 그누보드 5.5.4 로
업데이트 한 후 기존 라이브러리 (Excel)로 엑셀 자료를 서버에 업로드 하면 그냥 멈춥니다.
PHP 호환문제로 상당히 큰 문제라 구글링 하면서 될 수 있는 방법을 찾아서
드디어 성공 했기에 여기에 올려 봅니다.
엑셀라이브러리는 PHPSpreadsheet (composer 없이) 처리 하였습니다.
필요한 autoload.php나 psr.php 는 안에 포함되어 있습니다.
먼저 이 파일을 저는 테마의 lib에 그대로 압축 풀기를 했습니다.
경로는 Apache24 \ htdocs \ ??? \ theme \ ??? \ lib \ PhpOffice
(기본 말고 테마로 한 이유는 나중에 그누보드 순정을 건들면 별로라서...)
혹 다른 폴더에 압축해제하더라도 변수만 변경해 주시면 됩니다. (예시1)
require_once(G5_THEME_PATH.'/lib/PhpOffice/Psr/autoloader.php'); //설치폴더 변경시 G5_THEME_PATH 수정요함
require_once(G5_THEME_PATH.'/lib/PhpOffice/PhpSpreadsheet/autoloader.php'); //설치폴더 변경시 G5_THEME_PATH 수정요함
$reader = new PhpOffice\PhpSpreadsheet\Reader\Xls(); //업로드용 엑셀은 xls 입니다.
//Xlsx로 변경시
// $reader = new PhpOffice\PhpSpreadsheet\Reader\Xlsx();
// //업로드용 엑셀을 받으신 후 포멧을 xlsx 로 저장하시면 됩니다.
순서는
excel_up1.php 에서 파일을 선택(신규 데이터 입력만 구현)한 후
excel_up2.php 에서 실제 mysql로 넘어 갑니다.
excel_up2.php 안에 wr_subjcet의 중복체크하여 나중에 표시해 줍니다.
제가 사용하는 wr_subject는 D2022-xxxx (4개 숫자포맷으로 되어 있습니다.)
필요하신 입력폼 형태를 정의 하시고 $wr_1 ~ $wr_xxx 설정하세요
* 중간에 날짜형태 2022-04-12 를 PHPSpreadsheet 로 읽어 드리면
45563 이렇게 5글자로 바뀌어서 중간에 함수를 넣어 놓았습니다.
function time_convert($time) { //45563 날짜값을 날짜포맷변경
$t = ( $time - 25568 ) * 86400-60*60*9; // 25569 : -1 daty
$t = round($t*10)/10;
$t = date('Y-m-d',$t);
return $t;
}
그리고 중요한 것이 처음 use 선언을 하지 않으시면 에러가 납니다.
<?php
include_once('./_common.php');
use PhpOffice\PhpSpreadsheet\Spreadsheet; //처음 선언해야 함.
use PhpOffice\PhpSpreadsheet\Reader\Xls; //처음 선언해야 함.
//Xlsx를 사용하실려면 바꾸세요.
//use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
error_reporting(E_ALL);
ini_set("display_errors", 1);
엑셀 자료 읽어 드릴때 array가 0 아니고 1부터 입니다.
그리고 헤더를 제외한 데이터는 2부터 입니다. (주의)
for ($i=2; $i<=count($data);$i++ ){ //실제데이터는 2부터..
잘 사용하시길 바랍니다.
!-->!-->!-->!-->
7
댓글 19개
엑셀파일 업로드, 다시 엑셀 템플릿으로 다운로드 사용 중인데 매뉴얼도 나름 잘 되어 있고 기능이 대단하더군요.
$reader->setReadDataOnly(true);
$data = $spreadsheet->getSheet(0)->toArray(null,true,true,true); // >getSheet(0) 첫번째 시트 / 두번째는 getSheet(1)
//print_r2($data); 엑셀자료가 제대로 인식 되는지 하세요.
......
$wr_datetime = time_convert($data[$i]['A']);
$wr_subject = $data[$i]['B'];
$wr_1 = time_convert($data[$i]['C']);
$wr_2 = $data[$i]['D'];
$wr_3 = $data[$i]['E'];
$wr_4 = $data[$i]['F'];
$wr_5 = $data[$i]['G'];
$wr_6 = $data[$i]['H'];
저는 8개 필드로 엑셀파일에서 한줄씩 읽어서 변수로 받으면 데이터가 없는 줄에서 완료가 됩니다.
예전 버전인 Excel 라이브러리와 다른점이 엑셀의 열이 숫자로 표현 되었지만,
현재의 PHPSpreadsheet 에서는 A , B, C , .... AA..AB.. 처럼 숫자가 아니고 영문으로 되어있기에
이부분만 주의 하시면 어떤 방대한 자료도 한번에 DB로 갈수 있습니다.
또한 print_r2($data) 에서 주석처리를 푸시고 이하 줄부터는 주석처리 하신 후에 자료가 제대로 읽어 드리는지 먼저 확인하세요. 읽어 드릴때는 전체(헤더포함)로 표시 되어 있어야 정상입니다.
그럼..
적용은 게시판스킨에
<a href='<?php echo "../excel/excel_up1.php?bo_table=".$bo_table; ?>' class="btn_admin btn2" ><i class="fa fa-user-circle" aria-hidden="true"></i> Excel Upload </a>
이런식으로 링크를 걸었구요 업로드까지는 성공했습니다.
한데 excel_up12.php 78행에서 에러가 생겨서 코드를보니
$temp3 = substr($temp1, -4, 4) + 1 ; // 마지막번호 +1
이렇게 되어있어서 혹시나해서 아래와같이 뒤에 + 1 을 지워보니 입력은되지만 완료후 무슨 에러메세지가 뜨긴하네요.. 정상작동은 되니 뭐 상관없겠죠? 감사합니다
$temp3 = substr($temp1, -4, 4) ; // 마지막번호 +1
엑셀자료 업로드 자료~
너무 너무 감사를 드립니다~~
좌충우돌 하면서 겨우 넣었으나, 자료가 들어가지 않는부분이 있어서
미터강님과 많은 고수님들께 문의드려봅니다~~
wr_content 가 초기 자료에는 wr_subject에서 복사 받는 구조로 되어있던데요~
엑셀자료가 DB에 정상적으로 들어 가는데
wr_content 만 들어가지 않습니다
뭐가 문제가 되는것일까요? 문의드려봅니다~
고수님들의 답변에 미리 감사를 드립니다~~ [꾸벅]
다른내용은 동일하며
수정한 문제의 excel_up2.php 내용 첨부파일 포함 첨부드려봅니다 --------------------
먼저 wr_content는 엑셀(register_excel.xls)에서 읽어 드리지 않습니다. 이 부분을 엑셀에서 데이터 추가하셨으면 가능할수도 있고,
두번째로 DB의 컬럼에 wr_content가 있는지 확인해 보시고 다른이름의 경우는 sql의 이름정의(excel_up2.php)를 바꾸시거나 wr_subject로 하셔도 무방합니다.
저의 경우는 별도의 코멘트를 wr_content로 사용하고 있고, 엑셀을 통해서 DB에 업로드 하고 있습니다.
필요한 컬럼에 필요한 데이터를 엑셀로 작업하시면 되십니다.
참조하세요
composer 를 사용한 PHPSpreadsheet 를 권고 드립니다.
버전업이 조금 되어 있는데 컴포저 없이는 진행되지 않아서
가능하시면 내용만 참조하시고 틀 자체는 composer로 설치 진행하시면 편하십니다.
아직 초보 세네기여서
composer 처음 들어보고, 아는게 전혀 없어서 ㅜ.ㅡ
조언 감사를 드립니다~
그래도 좌충우돌~ 해결은 했습니다~~
142줄에
wr_content
추가하니까 적용되었습니다~
혹! 다른 더 좋은 방법 있으면 말씀 부탁드립니다~
감사를 드립니다~~^^
저의 해결 방법은 첨부 이미지 참고해주세요~^^*
wr_content는 그누보드에서 기본적으로 만들어지는 DB컬럼입니다.
admin의 "sql_write.sql"를 열어보시면
CREATE TABLE `__TABLE_NAME__` (
`wr_id` int(11) NOT NULL AUTO_INCREMENT,
`wr_num` int(11) NOT NULL DEFAULT '0',
`wr_reply` varchar(10) NOT NULL,
`wr_parent` int(11) NOT NULL DEFAULT '0',
`wr_is_comment` tinyint(4) NOT NULL DEFAULT '0',
`wr_comment` int(11) NOT NULL DEFAULT '0',
`wr_comment_reply` varchar(5) NOT NULL,
`ca_name` varchar(255) NOT NULL,
`wr_option` set('html1','html2','secret','mail') NOT NULL,
`wr_subject` varchar(255) NOT NULL,
`wr_content` text NOT NULL,
`wr_seo_title` varchar(255) NOT NULL DEFAULT '',
`wr_link1` text NOT NULL,
`wr_link2` text NOT NULL,
`wr_link1_hit` int(11) NOT NULL DEFAULT '0',
`wr_link2_hit` int(11) NOT NULL DEFAULT '0',
`wr_hit` int(11) NOT NULL DEFAULT '0',
`wr_good` int(11) NOT NULL DEFAULT '0',
`wr_nogood` int(11) NOT NULL DEFAULT '0',
`mb_id` varchar(20) NOT NULL,
이하생략
와 같이 wr_content가
DB의 테이블을 만들때
자동적으로 컬럼을 만들게 되어 있습니다.
따라서 wr_content가 다른 테이블에 없을때는
한줄을 추가해 주시면 아주 간단히 해결될수 있습니다.
이상입니다.
아래와 같은 에러가 뜨는데 해결 방법을 알고 싶습니다.
Parse error: syntax error, unexpected '=' in /home1/******/public_html/skin/board/check/excel/PhpOffice/PhpSpreadsheet/Reader/Xls.php on line 1106
// calculate the width and height of the shape
[$startColumn, $startRow] = Coordinate::coordinateFromString($spContainer->getStartCoordinates());
[$endColumn, $endRow] = Coordinate::coordinateFromString($spContainer->getEndCoordinates());
예를들어
$wr_subject = $data[$i]['B']; 에서
B 대신 B1 이나 B6처럼 없는 값을 넣어버리면 생길수 있습니다.
엑셀 열어 보셨을때 행은 숫자 1부터 시작할 것이고, 열은 A B C ....AA AB ...
즉 $data[1]['A'] 혹은 엑셀 행/열 에 표시된대로 기입을 하셔야 되지
다른 경우 $data['A1'] 처럼 행/열 구분없는 경우, $data[1]['A1'] 처럼 이상값을 넣는 경우는
Parse error (읽기 오류)가 나올 수 있습니다.
행은 1......숫자
열은 A,B,C,....AA,AB... 대문자 입니다.(소문자는 안될겁니다)
Xls.php가 문제는 없을것이고, 이것을 읽어 드리는 데이터가 매핑되는 excel??.php의 내용이
정확한지 보시면 될것 같습니다.
$wr_subject =$data[$i]['B']; 에서 $data[$i]['B'] 의 데이터가 '=' 라면
$wr_subject =$data[$i]['B']; -> $wr_subject ==; 이렇게 되는데...당연 에러가 나는게 정상이겠죠
데이터가 원하는 값인지, 그리고 바로 앞의 행열 변수가 제대로 있는지 확인을 해주시기 바랍니다.