import * as XLSX from 'xlsx'; /** * Blank input template with the three sheets (교각 · IP · 받침) and the headers the parser looks for. * Value cells are left empty on purpose: pre-filled names would become rows with no 교각명 and raise E05. * Row 1–2 are notes; the parser finds the headers anywhere on the sheet. */ export function buildTemplateWorkbook(): XLSX.WorkBook { const wb = XLSX.utils.book_new(); const note = (text: string) => [text]; const pier = [ note('교각 정보 1행당 교각 1기. 교각명·교각형식(T형/2주형/3주형)·기초 형식(말뚝기초/직접기초/현장타설말뚝)을 적습니다.'), note('방위각은 75°56\'55.9" 형식으로 적습니다. 머리글 행은 바꾸지 마세요.'), ['교각명', '교각형식', '두부보 EL_m', '기초 하단 EL_m', '지반고 EL_m', '기초 형식', '말뚝길이_mm', '두부보 폭_mm', '두부보 길이_mm', '기둥갯수'], ]; const ip = [ note('IP1–IP4의 좌표(국토좌표계, m)와 코핑 꺾임각(°)을 적습니다. 교각명은 교각 정보와 같아야 합니다.'), note('IP2는 참고용입니다. 프로그램이 IP1–IP3의 1:9 내분점으로 다시 계산해 비교합니다.'), ['교각명', 'IP점', 'x_m', 'y_m', '코핑 꺾임각'], ]; const bearing = [ note('받침 1행당 받침 1개. 전열·후열 수는 같아야 합니다. 위치는 전열 또는 후열.'), note('z_m은 받침 EL(m), 방위각은 거더 방향입니다.'), ['교각명', '받침번호', 'x_m', 'y_m', 'z_m', '방위각', '위치', '교좌면_EL'], ]; XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(pier), '교각'); XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(ip), 'IP'); XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(bearing), '받침'); return wb; }