728x90

php 에서도 가능하고 npm 으로도 설치가 가능해서 vue 나 react 에서도 가능한 스크립트다. 

 

상단에 아래와 같이 스크립트 url 을 추가해 주고 인쇄 되어야 하는 content 같은 div 아이디 값을 지정해 주고 .save 를 주면 pdf 로 다운로드가 가능하다. pdf 다운로드는 실제 변환되는 걸로 코딩을 하려면 무척 시간이 많이 걸리고 css 스타일도 inline 으로 밖아야 해서 코드도 무척 길어 지는데 아래와 같은 스크립트는 특정 div 만도 가능해서 좋은거 같다. 

<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>

 

pdf 다운로드 기능이 필요 하다면 참고해 보면 좋겠다.

var element = document.getElementById('content'); // PDF로 변환할 HTML 요소
html2pdf()
    .from(element)
    .save('document.pdf'); // 저장할 파일 이름

 

npm install html2pdf.js

 

728x90
728x90

다중으로 보내야 하는 경우 [] 괄호로 배열로 보내곤 하는데 이때 [] 괄호 안에 유니크한 번호를 넣으면 해당 번호를 기준으로 그룹 단위로 데이터를 테이블에 쌓을 수 있다. 요즘은 json 형태의 트리 구조로 데이터를 많이 잡기도 해서 조금 예스러운 코딩 일 수 있지만 종종 필요할 때가 있으니 참고하면 좋겠다. 

 

 

아래는 form 태그와 php 백 단에서 어떻게 처리되는지 에시를 보여준다.

<form method="POST" action="/your-endpoint">
    <table>
        <tr>
            <th>엘리베이터 여부</th>
            <td>
                <div class="com_chk__wrap">
                    <input type="hidden" name="cost_type[0]" value="189"> <!-- categories 189 : 엘리베이터여부 -->
                    <label><input type="radio" name="elevator_avail[0]" value="y">있음</label>
                    <label><input type="radio" name="elevator_avail[0]" value="n">없음 (있으나 사용 못 함)</label>
                </div>
            </td>
            <td class="td_center"><input type="number" name="labor_cost[0]" class="input num" value=""></td>
            <td class="td_center"><input type="number" name="margin_cost[0]" class="input num" value=""></td>
            <td class="td_center"><span class="">30,000원</span></td>
        </tr>
        <tr>
            <th>짐 여부</th>
            <td>
                <div class="com_chk__wrap">
                    <input type="hidden" name="cost_type[1]" value="188"> <!-- categories 188 : 짐 여부 -->
                    <label><input type="radio" name="luggage_avail[1]" value="y">있음</label>
                    <label><input type="radio" name="luggage_avail[1]" value="n">없음 (있으나 사용 못 함)</label>
                </div>
            </td>
            <td class="td_center"><input type="number" name="labor_cost[1]" class="input num" value=""></td>
            <td class="td_center"><input type="number" name="margin_cost[1]" class="input num" value=""></td>
            <td class="td_center"><span class="">30,000원</span></td>
        </tr>
        <!-- 추가적인 tr 요소들... -->
    </table>
    <button type="submit">제출</button>
</form>
<?php
// 데이터베이스 연결
$mysqli = new mysqli("localhost", "username", "password", "database");

// 연결 확인
if ($mysqli->connect_error) {
    die("Connection failed: " . $mysqli->connect_error);
}

// POST 데이터 수신
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 각 항목 반복 처리
    foreach ($_POST['cost_type'] as $index => $costType) {
        // 엘리베이터 여부
        $availKey = 'elevator_avail[' . $index . ']';
        $laborCostKey = 'labor_cost[' . $index . ']';
        $marginCostKey = 'margin_cost[' . $index . ']';

        $avail = isset($_POST[$availKey]) ? $mysqli->real_escape_string($_POST[$availKey]) : '';
        $laborCost = isset($_POST[$laborCostKey]) ? (int)$_POST[$laborCostKey] : 0;
        $marginCost = isset($_POST[$marginCostKey]) ? (int)$_POST[$marginCostKey] : 0;
        $totalCost = $laborCost + $marginCost;

        // INSERT 쿼리 작성
        $query = "INSERT INTO estimate_extra_cost (est_number, cost_type, add_postion, title, title_code, etc1, labor_cost, margin_cost, total_cost) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";

        // 준비된 문을 사용하여 실행
        $stmt = $mysqli->prepare($query);

        // 필요한 값을 설정
        $estNumber = 'E001'; // 실제 사용하려는 값으로 변경
        $addPosition = 'etc'; // 필요에 따라 조정
        $title = ($costType == 189) ? '엘리베이터 여부' : '짐 여부'; // 조건에 따라 제목 설정
        $titleCode = ($costType == 189) ? 'CATEGORY_ELEVATOR' : 'CATEGORY_LUGGAGE'; // 카테고리 코드 설정

        // 문장에 파라미터 바인딩
        $stmt->bind_param("sssssiiiii", $estNumber, $costType, $addPosition, $title, $titleCode, $avail, $laborCost, $marginCost, $totalCost);
        $stmt->execute();
    }

    // 준비된 문 종료
    $stmt->close();
}

// 데이터베이스 연결 종료
$mysqli->close();
?>
728x90
728x90

프로그램 작업을 하다 보면 견적서 같은 작업에서 견적서 번호를 유니크하게 생성해야 하는 경우가 종종 있다. 고객사에서는 번호를 한달에 몇건을 체크하고 싶어서 순차적으로 증가되게 해달라고 요청하시는 경우가 종종 있다. 그래서 주로 날짜와 뒷번호는 순번으로 채워지곤 하는데 아래 예시는 일자별 견적서 번호를 유니크하게 생성하는 로직이다. 

 

이때는 테이블 하나에서 해결하려고 하면 많이 복잡해 지니 차라리 번호만 관리하는 테이블을 하나 더 만드는것이 좋다. 또한 다른사람이 동일하게 접속해서 들어가더라도 순서대로 번호가 증가해서 그 키값을 가지고 있는거라 예약번호나 견적서 번호 같은걸 생성 해야 할때 참고 하면 좋겠다.  

CREATE TABLE temp_estimate_numbers (
    id INT AUTO_INCREMENT PRIMARY KEY,
    est_number VARCHAR(20) NOT NULL UNIQUE
);

 

테이블 쿼리문과 번호 생성하는 코드를 php 로 아래와 같이 메모해 본다. 

$pdo = dbconn(); // 데이터베이스 연결

// 견적서 번호 생성
$date = date('ymd');
$max_number = QRY_MAX("temp_estimate_numbers", " AND est_number LIKE '$date%'", "est_number");

if ($max_number) {
    $sequence = intval(substr($max_number, -3)) + 1; // 마지막 3자리에서 순번 증가
} else {
    $sequence = 1; // 기존 주문이 없으면 1로 시작
}

$orderNumber = str_pad($sequence, 3, '0', STR_PAD_LEFT);
$estimateNumber = $date . '-' . $orderNumber;

// 임시 테이블에 저장
$insert_sql = "INSERT INTO temp_estimate_numbers (est_number) VALUES ('$estimateNumber')";
$stmt = $pdo->prepare($insert_sql);

// 실행
if ($stmt->execute()) {
    echo "견적서 번호가 성공적으로 저장되었습니다: " . $estimateNumber;
} else {
    echo "저장 중 오류 발생.";
}
728x90
728x90

php 에서 pdf 파일로 다운로드 하는 방법은 몇가지가 있는데 그중 컴포저를 설치 했을 경우의 예시를 들어 본다. 아래와 같이 tecnickcom/tcpdf 로 컴포저를 설치하고 적용 방법은 아래에 3가지 경우로 예시를 메모해 본다. 

 

 

보통은 window.print() 로 날리면 해당 화면이 출력하기 모듈이 뜨면서 거기서 pdf 로 바로 다운로드가 가능한데 pdf 로 바로 다운이 되어야 하는 경우는 아래와 같이 수정을 해야 한다.  

composer require tecnickcom/tcpdf

 

1. tcpdf 를 사용해서 $pdf 로 생성하는 방법 

<?php
require_once('vendor/autoload.php');

// PDF 문서 생성
$pdf = new TCPDF();

// 문서 정보 설정
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Your Name');
$pdf->SetTitle('견적서');
$pdf->SetSubject('견적서 예제');
$pdf->SetKeywords('TCPDF, PDF, example, test, guide');

// 페이지 추가
$pdf->AddPage();

// 제목 추가
$pdf->SetFont('helvetica', 'B', 20); // 제목 폰트 설정
$pdf->Cell(0, 10, '견적서', 0, 1, 'C');
$pdf->Ln(10); // 줄 바꿈

// 테이블 데이터
$tableData = [
    ['항목', '수량', '단가', '합계'],
    ['상품 A', '2', '50000', '100000'],
    ['상품 B', '1', '30000', '30000'],
    ['상품 C', '3', '20000', '60000'],
];

// 테이블 스타일 설정
$pdf->SetFont('helvetica', 'B', 12); // 헤더 폰트 설정
$pdf->SetFillColor(200, 220, 255); // 헤더 배경 색상
$pdf->Cell(40, 10, $tableData[0][0], 1, 0, 'C', 1);
$pdf->Cell(40, 10, $tableData[0][1], 1, 0, 'C', 1);
$pdf->Cell(40, 10, $tableData[0][2], 1, 0, 'C', 1);
$pdf->Cell(40, 10, $tableData[0][3], 1, 1, 'C', 1);

// 테이블 데이터 출력
$pdf->SetFont('helvetica', '', 12); // 데이터 폰트 설정
$pdf->SetFillColor(255, 255, 255); // 데이터 배경 색상

foreach ($tableData as $key => $row) {
    if ($key > 0) { // 첫 번째 행은 이미 출력했으므로 생략
        $pdf->Cell(40, 10, $row[0], 1, 0, 'C', 1);
        $pdf->Cell(40, 10, $row[1], 1, 0, 'C', 1);
        $pdf->Cell(40, 10, $row[2], 1, 0, 'C', 1);
        $pdf->Cell(40, 10, $row[3], 1, 1, 'C', 1);
    }
}

// 하단에 직인 이미지 추가
$pdf->Ln(10);
$imageFile = 'path/to/your/seal.png'; // 직인 이미지 경로
$pdf->Image($imageFile, 150, 250, 40, 40, 'PNG', '', '', false, 300, '', false, false, 0, false, false, false);

// PDF 파일 다운로드
$pdf->Output('견적서.pdf', 'D');
?>

 

2. html 태그를 css 파일을 적용해서 중간에 추가 하는 경우

<?php
require_once('vendor/autoload.php');

// PDF 문서 생성
$pdf = new TCPDF();

// 문서 정보 설정
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Your Name');
$pdf->SetTitle('견적서');
$pdf->SetSubject('견적서 예제');
$pdf->SetKeywords('TCPDF, PDF, example, test, guide');

// 페이지 추가
$pdf->AddPage();

// CSS 파일 포함
$css = file_get_contents('path/to/styles.css'); // CSS 파일 경로
$html = '
<style>' . $css . '</style>
<h1>견적서</h1>
<table>
    <thead>
        <tr>
            <th>항목</th>
            <th>수량</th>
            <th>단가</th>
            <th>합계</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>상품 A</td>
            <td>2</td>
            <td>50000</td>
            <td>100000</td>
        </tr>
        <tr>
            <td>상품 B</td>
            <td>1</td>
            <td>30000</td>
            <td>30000</td>
        </tr>
        <tr>
            <td>상품 C</td>
            <td>3</td>
            <td>20000</td>
            <td>60000</td>
        </tr>
    </tbody>
</table>
<br>
<img src="path/to/your/seal.png" alt="직인" width="100" height="100" style="float:right;">
';

// HTML 콘텐츠 출력
$pdf->writeHTML($html, true, false, true, false, '');

// PDF 파일 다운로드
$pdf->Output('견적서.pdf', 'D');
?>

 

3. html 코드가 있는 php 파일을 include 해서 적용하는 방법

<?php
require_once('vendor/autoload.php');

// PDF 문서 생성
$pdf = new TCPDF();

// 문서 정보 설정
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Your Name');
$pdf->SetTitle('견적서');
$pdf->SetSubject('견적서 예제');
$pdf->SetKeywords('TCPDF, PDF, example, test, guide');

// 페이지 추가
$pdf->AddPage();

// HTML 파일 포함
ob_start(); // 출력 버퍼링 시작
include('aa.php'); // aa.php 파일 포함
$html = ob_get_clean(); // 버퍼 내용을 변수로 저장하고 버퍼 비우기

// HTML 콘텐츠 출력
$pdf->writeHTML($html, true, false, true, false, '');

// PDF 파일 다운로드
$pdf->Output('견적서.pdf', 'D');
?>

 

각 상황에 맞게 사용하는 것이 좋겠다. 컴포저 설치시에는 실서버와 동일한 php 버전에서 컴포저를 설치해야 버전 이슈가 없는 점은 참고해야 한다. 

728x90
728x90

정산내역을 작업하다 보면 추가 금액을 입력하는 경우가 종종 생긴다. 전산으로 모두 계산하지만 추가 비용을 지불해야 한다던지 추가 비용을 차감해야 한다던지 하는 예외적인 상황은 별도로 입력해주는 폼을 추가 해주고 db 에 저장해 주는것이 좋다. 

<form action="process.php" method="post">
    <td>
        <select name="operation" id="operation" style="width:60px;">
            <option value="+">+</option>
            <option value="-">-</option>
        </select>
        <input type="number" name="extra_amount" class="w180" required title="금액">원
        <button type="submit">전송</button>
    </td>
</form>

 

select box 에서 기호를 선택하고 입력하는 방식으로 구현 한다면 태그를 작성하고 post 로 받는 화면은 아래와 같이 floatval 로 변환해 주어야 마이너스로 입력이 된다. db 에 필드도 float 로 잡아 주어야 한다. 

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $operation = $_POST['operation'];
    $amount = $_POST['extra_amount'];

    // 금액에 + 또는 - 기호 붙이기
    $extra_amount = ($operation === '-') ? -floatval($amount) : floatval($amount); // 입력값을 float으로 변환

    // 선생님 정산 테이블 업데이트
    $paramArray = [];   
    $paramArray = compact('extra_amount'); 
    $paramArray["payment"] = $total_amount - $tax + $extra_amount; 

    // 데이터베이스 업데이트
    $rsArry = $this->UpdateData("reservation_settle_teacher", $paramArray, $where_com);
}
728x90
728x90

php 엑셀다운로드 예시 
 
php 코드에서 엑셀다운로드를 사용 하려면 vendor 에서 설치하고 사용해야 한다. 
composer require phpoffice/phpspreadsheet
컴포저에서 설치 후 이용해야 한다. 

<?php
require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

function downloadExcel($filename = 'example.xlsx') {
    // 새로운 스프레드시트 객체 생성
    $spreadsheet = new Spreadsheet();

    // 시트 1 생성
    $sheet1 = $spreadsheet->getActiveSheet();
    $sheet1->setTitle('첫 번째 시트');
    
    // 헤더 추가
    $sheet1->setCellValue('A1', '헤더 1');
    $sheet1->setCellValue('B1', '헤더 2');
    $sheet1->setCellValue('A2', '데이터 1');
    $sheet1->setCellValue('B2', '데이터 2');

    // 시트 2 생성
    $sheet2 = $spreadsheet->createSheet();
    $sheet2->setTitle('두 번째 시트');
    
    // 헤더 추가
    $sheet2->setCellValue('A1', '헤더 A');
    $sheet2->setCellValue('B1', '헤더 B');
    $sheet2->setCellValue('A2', '데이터 A');
    $sheet2->setCellValue('B2', '데이터 B');

    // 파일 다운로드를 위한 헤더 설정
    header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    header("Content-Disposition: attachment; filename=\"$filename\"");
    header('Cache-Control: max-age=0');

    // 엑셀 파일 작성
    $writer = new Xlsx($spreadsheet);
    $writer->save('php://output');
    exit;
}

// 함수 호출
downloadExcel('내_엑셀파일.xlsx');
?>

 
엑셀업로드예시

<?php
$host = 'localhost'; // 데이터베이스 호스트
$db = 'your_database'; // 데이터베이스 이름
$user = 'your_username'; // 사용자 이름
$pass = 'your_password'; // 비밀번호
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
    throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
?>

 
파일 업로드 후 db 에 insert 하는 예시

<?php
require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\IOFactory;

// 파일 업로드 처리
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['excel_file'])) {
    $file = $_FILES['excel_file']['tmp_name'];

    // 엑셀 파일 읽기
    $spreadsheet = IOFactory::load($file);

    // 모든 시트 순회
    foreach ($spreadsheet->getAllSheets() as $sheet) {
        $sheetData = $sheet->toArray();

        // 첫 번째 행은 헤더로 가정하고 데이터 삽입
        for ($row = 1; $row < count($sheetData); $row++) {
            $data = $sheetData[$row];

            // 데이터 삽입 쿼리 (여기서 예시로 'your_table'을 사용)
            $stmt = $pdo->prepare("INSERT INTO your_table (column1, column2) VALUES (?, ?)");
            $stmt->execute([$data[0], $data[1]]);
        }
    }

    echo "데이터가 성공적으로 삽입되었습니다.";
}
?>

<!-- HTML 업로드 폼 -->
<form method="post" enctype="multipart/form-data">
    <input type="file" name="excel_file" accept=".xlsx, .xls" required>
    <button type="submit">업로드</button>
</form>
728x90
728x90

php 작업중 여러 테이블에 데이터를 insert 할때는 트랜지션을 걸고 모든 데이터가 완료 되었을때 commit 을하고 하나라도 오류가 있을 경우에는 rollback 작업을걸어 준다. 이때 insert 하고 난 데이터는 마지막에 commit 되기 때문에 excute 에서는 데이터 조회가 되지 못하는데 설정값을 트랜지션 시작 지점 위에 선언해 주면 excute 까지만 되어도 해당 데이터는 insert 된것으로 인지하고 select 문을 실행한다. 

 

$pdo->exec("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
try {
    // 데이터베이스 연결 설정
    $pdo = new PDO('mysql:host=localhost;dbname=your_database', 'username', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // 트랜잭션 격리 수준 설정
    $pdo->exec("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");

    // 트랜잭션 시작
    $pdo->beginTransaction();

    // 삽입할 데이터 배열
    $dataToInsert = [
        ['value1' => '데이터1', 'value2' => '데이터2'],
        ['value1' => '데이터3', 'value2' => '데이터4'],
        // 추가 데이터...
    ];

    // 데이터 삽입 및 체크
    foreach ($dataToInsert as $data) {
        // 데이터 삽입
        $stmt = $pdo->prepare("INSERT INTO your_table (column1, column2) VALUES (:value1, :value2)");
        $stmt->execute([':value1' => $data['value1'], ':value2' => $data['value2']]);

        // 삽입된 데이터 체크
        $lastId = $pdo->lastInsertId();
        $checkStmt = $pdo->prepare("SELECT * FROM your_table WHERE id = :id");
        $checkStmt->execute([':id' => $lastId]);
        $result = $checkStmt->fetch();

        if (!$result) {
            // 데이터가 존재하지 않으면 롤백하고 종료
            $pdo->rollBack();
            echo "데이터 삽입에 실패했습니다: " . $data['value1'];
            exit;
        }
    }

    // 모든 데이터가 정상적으로 삽입되면 커밋
    $pdo->commit();
    echo "모든 데이터가 성공적으로 삽입되었습니다.";

} catch (Exception $e) {
    // 예외 처리
    $pdo->rollBack();
    echo "오류 발생: " . $e->getMessage();
}
 

 

 

트랜지션에는 4가지 종류가 있는데 각 상황에 맞게 시작지점에 선언해 주면 된다.

 

 

READ UNCOMMITTED: 다른 트랜잭션이 커밋하지 않은 변경 사항을 읽을 수 있습니다. (Dirty Reads 가능)
READ COMMITTED: 다른 트랜잭션이 커밋한 변경 사항만 읽을 수 있습니다. (Dirty Reads 방지)
REPEATABLE READ: 트랜잭션 시작 시점의 데이터를 읽습니다. (Phantom Reads 방지)
SERIALIZABLE: 가장 높은 격리 수준으로, 트랜잭션이 직렬화된 것처럼 동작합니다. (Phantom Reads 및 모든 충돌 방지)

 

한참 찾았는데 실제로 내가 해봤을때 되는 코드는 READ UNCOMMITTED 설정이니 참고 하면 좋겠다.

728x90
728x90

회원가입 시 회원 비밀번호는 복호화로 암호가 풀어져서는 안된다. 그래서 단방향 암호화를 사용하는데 예전에는 md5 를 사용 했지만 요즘은 php 내장 함수 password_hash 가 유용한거 같다.

<?php
$password = '사용자_입력_비밀번호';
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
echo $hashedPassword;
?>

 

저장 할때는 password_hash 로 하고 암호를 비교 할때는 password_verify 로 사용한다. 

<?php
$inputPassword = '사용자_입력_비밀번호';
$storedHashedPassword = '데이터베이스에서_가져온_해시된_비밀번호';

if (password_verify($inputPassword, $storedHashedPassword)) {
    echo '비밀번호가 일치합니다.';
} else {
    echo '비밀번호가 일치하지 않습니다.';
}
?>
728x90
728x90

php 에서 작업을 하다 보면 예전에는 엑셀 다운로드가 많았지만 요즘에는 pdf 로 다운 받기를 원한다.  tcpdf 사이트에서 무료로 다은 받을 수 있지만 한글이 깨지는 오류가 있다. 한글 폰트가 있어야지만 한글이 깨지지 않기 때문에 nanumbarungothicyethangul.php 파일과 폰트를 다운로드 해서 설정해주고 아래와 같이 코딩해주면 html 코드 그대로 pdf 파일로 다운로드가 가능하다. 

 

 

단 css 파일에 정의된 스타일은 사용이 되지 않고 태그 자체에 style 을 하드코딩으로 해주어야 한다. 그래서 테이블 코딩으로 하는것이 레이아웃이 깨지거나 하지 않아서 해당 출력물은 테이블 코딩을 별도로 진행하는 것이 좋다. 

<?php
	require_once "./tcpdf/tcpdf_import.php";  

/**
 * 헤더 변경을 위한 class 상속 후 재 정의
 */
class MYPDF extends TCPDF {

    //Page header
    public function Header() {
        // Logo
        $image_file = K_PATH_IMAGES.'logo_example.jpg';
        $this->Image($image_file, 10, 10, 15, '', 'PNG', '', 'T', false, 300, '', false, false, 0, false, false, false);
        // Set font
        $this->SetFont('helvetica', 'B', 15);

        // Title
        //$this->Cell(0, 15, 'www.example.com', 0, false, 'C', 0, '', 0, false, 'M', 'M');
    }
}

$pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, "UTF-8", false);
$pdf->SetCreator(PDF_CREATOR);

// set default header data
$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE, PDF_HEADER_STRING);

// set header and footer fonts
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));

// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);

// set margins
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);

// set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);

// set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);

$pdf->SetFont('nanumbarungothicyethangul', '', 12);
$pdf->AddPage();
//$pdf->writeHTMLCell(0, 0, "", "", $html, 0, 1, 0, true, "", true);










include $_SERVER["DOCUMENT_ROOT"]."/include/dbopen.php";
$sql = " select * from dual";

ob_start();
?>

<!doctype html>
<html><head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/> 
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>PDF 다운로드 예제</title>
</head>
<body>

<style type="text/css">
.table th, .table td {
    padding: 10px 16px;
    font-size: 15px;
    border: 1px solid #cccccc;
}	
</style>
				<p style="text-align:center; margin-bottom:50px; font-size:30px;">견적서</p>
 
                <table class="table">
                  <colgroup><col width="10%"><col width="10%"><col width="50%"><col></colgroup>
                  <tr>
                    <th style="padding: 10px 16px; font-size: 15px; border: 1px solid #cccccc;"rowspan="2">확인란</th>
                    <td rowspan="2">
                      <img src="도메인경로부터/img/img_confirm.png" style="width:80px;">
                    </td>                        
                    <td>데이터 내용 </td>
                  </tr>
                </table>
  
            </div>

</body>
</html>
<?php
$pdfData = ob_get_contents();
ob_end_clean();
 

// 테이블을 출력할 때 사용하는 방법
$pdf -> writeHTML($pdfData, true, false, false, false, '');

$pdf->Output(getcwd()."/example_test_01.pdf", "FI");

?>
728x90
728x90

산출물 작석시 파일명세서는 폴더내에 파일명을 모두 출력하고 메모를 해야 해서 php 코드로 파일명을 모두 출력하게 하면 조금 더 작성하기가 편해진다. root 기준의 폴더명을 적어 주고 해당 디렉토리에 아래 파일을 올리면 파일 리스트를 모두 출력 받을 수 있다. 

<?php
// 제외할 폴더와 경로를 배열로 정의합니다.
$excludedPaths = array(
    '/upload',
    '/plugin',
    '/assets/front/img',
    '/assets/front/fonts',
    '/assets/front/scss'
);

// 디렉토리 경로를 절대 경로로 설정합니다.
$directory = realpath('foldername');

// 디렉토리 내의 파일 및 폴더 목록을 가져옵니다.
listDirectoryContents($directory, $excludedPaths);

// 재귀적으로 디렉토리 내의 파일 및 폴더 목록을 출력하는 함수
function listDirectoryContents($dir, $excludedPaths) {
    $files = scandir($dir);
    foreach ($files as $file) {
        // 현재 디렉토리(.)와 상위 디렉토리(..)는 제외합니다.
        if ($file != '.' && $file != '..') {
            // 파일 또는 폴더의 전체 경로
            $filePath = $dir . '/' . $file;

            // 제외할 경로에 포함되어 있거나 파일인 경우 스킵합니다.
            if (in_array($filePath, $excludedPaths) || is_file($filePath)) {
                continue;
            }

            // 디렉토리인 경우 디렉토리명을 출력합니다.
            if (is_dir($filePath)) {
                echo $filePath . "<br>";
                // 하위 폴더가 있는 경우 해당 폴더를 탐색합니다.
                listDirectoryContents($filePath, $excludedPaths);
            }
        }
    }
}
?>

 

위 코드를 실행하면 웹페이지에 아래와 같이 하위폴더의 내역까지 모두 출력이 된다. 

foldername/views/front/your/mento.php
foldername/views/front/your/mento_view.php

 

디렉토리 명을 모두 출력하려면 아래와 같이 작성하면 된다.

<?php
// 제외할 폴더와 경로를 배열로 정의합니다.
$excludedPaths = array(
    '/upload',
    '/plugin',
    '/assets/front/img',
    '/assets/front/fonts',
    '/assets/front/scss' 
);

// 디렉토리 경로를 절대 경로로 설정합니다.
$directory = realpath('foldername');

// 디렉토리 내의 파일 및 폴더 목록을 가져옵니다.
listDirectoryContents($directory, $excludedPaths);

// 재귀적으로 디렉토리 내의 파일 및 폴더 목록을 출력하는 함수
function listDirectoryContents($dir, $excludedPaths) {
    $files = scandir($dir);
    foreach ($files as $file) {
        // 현재 디렉토리(.)와 상위 디렉토리(..)는 제외합니다.
        if ($file != '.' && $file != '..') {
            // 파일 또는 폴더의 전체 경로
            $filePath = $dir . '/' . $file;

            // 제외할 경로에 포함되어 있거나 파일인 경우 스킵합니다.
            $skip = false;
            foreach ($excludedPaths as $excludedPath) {
                if (strpos($filePath, $excludedPath) === 0) {
                    $skip = true;
                    break;
                }
            }
            if ($skip || is_file($filePath)) {
                continue;
            }

            // 디렉토리인 경우 디렉토리명을 출력합니다.
            if (is_dir($filePath)) {
                echo $filePath . "<br>";
                // 하위 폴더가 있는 경우 해당 폴더를 탐색합니다.
                listDirectoryContents($filePath, $excludedPaths);
            }
        }
    }
}
?>

 

$directory 를 기준으로 하위에 포함된 디렉토리까지 모두 출력해주니 폴더명으로 정리를 해야 할때 편리하다. 

728x90

+ Recent posts