Skip to content

Instantly share code, notes, and snippets.

@siteslave
Created October 1, 2024 16:19
Show Gist options
  • Save siteslave/d948ed8e3993c67ed6ea97d24ea1bb8f to your computer and use it in GitHub Desktop.
Save siteslave/d948ed8e3993c67ed6ea97d24ea1bb8f to your computer and use it in GitHub Desktop.

File model

// lib/server/file.ts

import excel from 'excel4node'
import { DateTime } from 'luxon'
import path from 'path'
import { v4 as uuidv4 } from 'uuid'

import { env } from '$env/dynamic/private'

export const exportPerson = async (/** @type {any[]} */ data) => {
    const wb = new excel.Workbook()
    wb.creator = 'สำนักงานเขตสุขภาพที่ 7'
    wb.created = new Date()
    wb.modified = new Date()

    const ws = wb.addWorksheet('ข้อมูลประชากรกลุ่มเป้าหมาย')

    const thDate = DateTime.now().setLocale('th').toLocaleString(DateTime.DATE_MED)

    ws.cell(1, 1).string('รายชื่อประชากลุ่มเป้าหมาย')
    ws.cell(2, 1).string('ข้อมูล ณ วันที่')
    ws.cell(2, 2).string(thDate)

    // header
    ws.cell(4, 1).string('ชื่อ - สกุล')
    ws.cell(4, 2).string('เพศ')
    ws.cell(4, 3).string('เลขที่')
    ws.cell(4, 4).string('หมู่')
    ws.cell(4, 5).string('ตำบล')
    ws.cell(4, 6).string('อสม.ประจำบ้าน')
    ws.cell(4, 7).string('โรคเบาหวาน')
    ws.cell(4, 8).string('โรคความดัน')

    let startCell = 5

    data.forEach((v) => {
        const fullname = `${v.first_name} ${v.last_name}`
        const sex = v.sex === '1' ? 'ชาย' : 'หญิง'
        // const address = `${v.address} หมู่ ${v.moo} ต.${v.sub_district_name}`
        const osmFullname = `${v.osm_first_name} ${v.osm_last_name}`
        const isDm = v.is_dm ? 'ใช่' : 'ไม่ใช่'
        const isHt = v.is_ht ? 'ใช่' : 'ไม่ใช่'

        ws.cell(startCell, 1).string(fullname)
        ws.cell(startCell, 2).string(sex)
        ws.cell(startCell, 3).string(`${v.address}`)
        ws.cell(startCell, 4).string(`${v.moo}`)
        ws.cell(startCell, 5).string(`${v.sub_district_name}`)
        ws.cell(startCell, 6).string(osmFullname)
        ws.cell(startCell, 7).string(isDm)
        ws.cell(startCell, 8).string(isHt)

        startCell++
    })

    const exportTmpDir = env.EXPORT_TMP_DIR ?? './tmp'

    var exportFile = `${uuidv4()}-${DateTime.now().toUnixInteger()}.xlsx`
    const filePath = path.join(exportTmpDir, exportFile)
    return new Promise((resolve, reject) => {
        wb.write(filePath, (/** @type {any} */ err, /** @type {any} */ stats) => {
            if (err) {
                console.error(err)
                reject(err)
            }
            resolve({ filePath, fileName: exportFile })
        })
    })
}

การใช้งาน

Routing

// file routes/file.ts
import { readFileSync } from 'fs'
import path from 'path'

import { env } from '$env/dynamic/private' // อ่านค่า environment

import * as fileModel from '$lib/server/models/file'

/** @type {import('./$types').RequestHandler} */
export async function GET({ url, locals }) {

    let data =  await dataModel.getResult() // ดึงข้อมูลจากฐานข้อมูล

    const filePath = await fileModel.exportPerson(data) // ส่งข้อมูลที่ได้ไปให้ file model เพื่อไปสร้าง excel file จากนั้นฟังก์ชันนี้จะคืนค่า path file ออกมา (โค้ดด้านบน)
    const buffer = readFileSync(filePath)
    const filename = path.basename(filePath)
    return new Response(buffer, {
        status: 200,
        headers: {
            'Content-Type': 'application/octet-stream',
            'Content-Disposition': `attachment; filename*=UTF-8''${encodeURIComponent(filename)}`,
        },
    })

}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment