테스트 사이트 - 개발 중인 베타 버전입니다

[엑셀라이브러리] 간단한 식자재 사용량 계산기 HTML

· 11개월 전 · 1258 · 3

[code]

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>식자재 소비량 계산기</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
    <style>
        body {
            background-color: #f8f9fa;
        }
        .container {
            max-width: 800px;
        }
    </style>
</head>
<body>
    <div class="container mt-5">
        <h1 class="text-center mb-4">식자재 소비량 계산기</h1>
        <div class="card mb-4">
            <div class="card-body">
                <h5 class="card-title">기간 선택</h5>
                <div class="row">
                    <div class="col-md-6 mb-3">
                        <label for="startDate" class="form-label">시작일</label>
                        <input type="text" id="startDate" class="form-control datepicker" placeholder="시작일 선택" required>
                    </div>
                    <div class="col-md-6 mb-3">
                        <label for="endDate" class="form-label">종료일</label>
                        <input type="text" id="endDate" class="form-control datepicker" placeholder="종료일 선택" required>
                    </div>
                </div>
                <p id="periodInfo" class="mt-2"></p>
            </div>
        </div>
        <div class="card">
            <div class="card-body">
                <form id="foodConsumptionForm">
                    <div id="foodItems">
                        <!-- 식자재 항목들이 여기에 추가됩니다 -->
                    </div>
                    <button type="button" id="addFoodItem" class="btn btn-secondary mt-3">
                        <i class="bi bi-plus-circle"></i> 식자재 추가
                    </button>
                    <button type="submit" class="btn btn-primary mt-3">계산하기</button>
                </form>
                <div id="results" class="mt-4">
                    <!-- 계산 결과가 여기에 표시됩니다 -->
                </div>
                <button id="exportExcel" class="btn btn-success mt-3" style="display: none;">
                    <i class="bi bi-file-earmark-excel"></i> 엑셀로 저장
                </button>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
    <script src="https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/ko.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.0/xlsx.full.min.js"></script>
    <script>
        let itemCount = 0;
        let startDate, endDate;

        flatpickr(".datepicker", {
            locale: "ko",
            dateFormat: "Y-m-d",
            onChange: function(selectedDates, dateStr, instance) {
                if (instance.element.id === "startDate") {
                    startDate = selectedDates[0];
                } else if (instance.element.id === "endDate") {
                    endDate = selectedDates[0];
                }
                updatePeriodInfo();
            }
        });

        function updatePeriodInfo() {
            if (startDate && endDate) {
                const diffTime = Math.abs(endDate - startDate);
                const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
                const diffWeeks = Math.ceil(diffDays / 7);
                const diffMonths = Math.ceil(diffDays / 30);
                const diffYears = Math.ceil(diffDays / 365);

                let periodText;
                if (diffDays < 7) {
                    periodText = `${diffDays}일`;
                } else if (diffDays < 30) {
                    periodText = `${diffWeeks}주`;
                } else if (diffDays < 365) {
                    periodText = `${diffMonths}개월`;
                } else {
                    periodText = `${diffYears}년`;
                }

                document.getElementById('periodInfo').textContent = `선택된 기간: ${periodText}`;
            }
        }

        function addFoodItem() {
            itemCount++;
            const foodItem = document.createElement('div');
            foodItem.className = 'food-item mb-3';
            foodItem.innerHTML = `
                <div class="row">
                    <div class="col-md-3">
                        <input type="text" class="form-control food-name" placeholder="식자재 이름" required>
                    </div>
                    <div class="col-md-3">
                        <input type="number" class="form-control consumption" placeholder="총 소비량" required>
                    </div>
                    <div class="col-md-3">
                        <select class="form-select unit" required>
                            <option value="">단위 선택</option>
                            <option value="개">개</option>
                            <option value="kg">kg</option>
                            <option value="리터">리터</option>
                            <option value="포기">포기</option>
                        </select>
                    </div>
                    <div class="col-md-3">
                        <button type="button" class="btn btn-danger remove-item">
                            <i class="bi bi-trash"></i> 삭제
                        </button>
                    </div>
                </div>
            `;
            document.getElementById('foodItems').appendChild(foodItem);

            foodItem.querySelector('.remove-item').addEventListener('click', function() {
                foodItem.remove();
            });
        }

        document.getElementById('addFoodItem').addEventListener('click', addFoodItem);

        document.getElementById('foodConsumptionForm').addEventListener('submit', function(e) {
            e.preventDefault();
            
            if (!startDate || !endDate) {
                alert('시작일과 종료일을 선택해주세요.');
                return;
            }

            const results = document.getElementById('results');
            results.innerHTML = '<h4>계산 결과</h4>';

            const foodItems = document.querySelectorAll('.food-item');
            const calculationResults = [];

            foodItems.forEach(item => {
                const name = item.querySelector('.food-name').value;
                const consumption = parseFloat(item.querySelector('.consumption').value);
                const unit = item.querySelector('.unit').value;

                const diffTime = Math.abs(endDate - startDate);
                const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));

                const dailyConsumption = (consumption / diffDays).toFixed(2);
                const weeklyConsumption = (consumption / diffDays * 7).toFixed(2);
                const monthlyConsumption = (consumption / diffDays * 30).toFixed(2);

                calculationResults.push({
                    name,
                    totalConsumption: consumption,
                    unit,
                    dailyConsumption,
                    weeklyConsumption,
                    monthlyConsumption
                });

                results.innerHTML += `
                    <div class="card mb-3">
                        <div class="card-body">
                            <h5 class="card-title">${name}</h5>
                            <p>총 소비량: ${consumption} ${unit}</p>
                            <p>일일 소비량: ${dailyConsumption} ${unit}</p>
                            <p>주간 소비량: ${weeklyConsumption} ${unit}</p>
                            <p>월간 소비량: ${monthlyConsumption} ${unit}</p>
                        </div>
                    </div>
                `;
            });

            document.getElementById('exportExcel').style.display = 'inline-block';
            window.calculationResults = calculationResults;
        });

        document.getElementById('exportExcel').addEventListener('click', function() {
            const wb = XLSX.utils.book_new();
            const data = window.calculationResults.map(item => ({
                '식자재 이름': item.name,
                '총 소비량': item.totalConsumption,
                '단위': item.unit,
                '일일 소비량': item.dailyConsumption,
                '주간 소비량': item.weeklyConsumption,
                '월간 소비량': item.monthlyConsumption
            }));
            const ws = XLSX.utils.json_to_sheet(data);
            XLSX.utils.book_append_sheet(wb, ws, "식자재 소비량");
            XLSX.writeFile(wb, "식자재_소비량_계산결과.xlsx");
        });

        // 페이지 로드 시 기본 식자재 항목 하나 추가
        addFoodItem();
    </script>
</body>
</html>

[/code]

 

식자재 소비량 계산기 기능 요약

1. 기간 선택
   - 시작일과 종료일 선택 가능
   - 선택된 기간에 따라 일/주/월/년 단위로 기간 정보 자동 표시

2. 식자재 항목 관리
   - 식자재 이름, 총 소비량, 단위 입력 가능
   - 새로운 식자재 항목 추가 및 삭제 기능

3. 소비량 계산
   - 선택된 기간 기준으로 각 식자재의 소비량 자동 계산
   - 일일, 주간, 월간 소비량 제공

4. 결과 표시
   - 각 식자재별 계산 결과를 카드 형태로 시각적 표시
   - 총 소비량, 일일 소비량, 주간 소비량, 월간 소비량 정보 제공

5. 엑셀 파일 저장
   - 계산 결과를 엑셀 파일로 저장 가능
   - 엑셀 파일의 항목명을 한글로 표시

6. 사용자 인터페이스
   - 반응형 디자인으로 다양한 기기에서 사용 가능
   - Bootstrap을 활용한 현대적이고 깔끔한 디자인

7. 기술 스택
   - HTML, JavaScript, CSS 사용
   - Bootstrap 5.3.3 프레임워크 활용
   - Flatpickr 라이브러리로 날짜 선택 기능 구현
   - SheetJS 라이브러리로 엑셀 파일 생성 기능 구현

댓글 작성

댓글을 작성하시려면 로그인이 필요합니다.

로그인하기

댓글 3개

11개월 전

안녕하세요! 혹시 영수증을 카메라로 정보 가져와서 간편 장부처럼 정리하고 엑셀로도 다운 가능하는 소스코드도 있나요?

11개월 전

@리오닥터 그럴려면 이미지분석 이루어지고 올바른 데이터 비교를 해서 입력시키고 외부 엑셀라이브러리도 사용해야해서 거의 AI기능에 가까운 기능같습니다~

11개월 전

https://api.ncloud-docs.com/docs/ai-application-service-ocr-ocrdocumentocr-receipt
네이버클로버 API에 영수증 인식모듈이 있는데 사용은 간편하지만 상당히 비싸더라구요... 

게시글 목록

번호 제목
18200
18195
18193
18181
18179
18173
18170
18164
18158
18155
18152
18151
18150
18140
18139
18138
18131
18130
18120
18119
18118
18117
18116
18111
18110
18108
18107
18106
18100
18090