TreeMap
무료 오픈소스 디스크 사용량 시각화 도구로, 사각형 트리맵·중복 파일 탐색·디스크 가득 예측·정리 시 파일을 휴지통으로만 이동한다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기เครื่องมือจัดการไฟล์ PDF/Excel/Word/รูปภาพ 16 ตัว ทำงานในเบราว์เซอร์ล้วน ไฟล์ไม่ถูกอัปโหลดขึ้นเซิร์ฟเวอร์
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
เว็บแปลง/จัดการไฟล์ PDF · Excel · Word · PowerPoint · รูปภาพ 70 เครื่องมือ ที่ประมวลผลในเครื่องผู้ใช้ทั้งหมด ไม่มีการอัปโหลดไฟล์ขึ้นเซิร์ฟเวอร์ และใช้งานได้แม้ไม่มีอินเทอร์เน็ต สร้างขึ้นเองทั้งหมด โดยถอดบทเรียนด้าน performance จากการวัดเว็บต้นแบบและงานวิจัยที่เก็บไว้ที่ .claude/research/2026-09-07-web-perf-clientside-converter.md และ .claude/research/2026-09-07-file-tools-market-scan.mdREADME 전문 보기 ↗
🔗 ใช้งานจริง: https://patcharasitp.github.io/filekit/ (ติดตั้งลงมือถือเป็นแอปได้ · ใช้ได้แม้ออฟไลน์)
เว็บแปลง/จัดการไฟล์ PDF · Excel · Word · PowerPoint · รูปภาพ 70 เครื่องมือ ที่ประมวลผลในเครื่องผู้ใช้ทั้งหมด ไม่มีการอัปโหลดไฟล์ขึ้นเซิร์ฟเวอร์ และใช้งานได้แม้ไม่มีอินเทอร์เน็ต
สร้างขึ้นเองทั้งหมด โดยถอดบทเรียนด้าน performance จากการวัดเว็บต้นแบบและงานวิจัยที่เก็บไว้ที่
.claude/research/2026-09-07-web-perf-clientside-converter.mdและ.claude/research/2026-09-07-file-tools-market-scan.md
เทียบกับเว็บต้นแบบ (bbellechy.github.io/ILoveMyJob) ที่โหลดไลบรารีทั้ง 9 ตัวแบบ blocking ตั้งแต่หน้าแรก
วัดด้วย Playwright + Chrome DevTools Protocol เงื่อนไขเดียวกันทั้งคู่ (เสิร์ฟจาก localhost, ไลบรารีชุดเดียวกัน):
วัดบน production จริง — ทั้งสองเว็บอยู่บน GitHub Pages เหมือนกัน เน็ตจริงเงื่อนไขเดียวกัน:
| ตัวชี้วัด | ต้นแบบ | FileKit | ผล |
|---|---|---|---|
| FCP — มือถือ Slow-4G + CPU ช้า 4× | 5,152 ms | 328 ms | เร็วขึ้น 15.7× |
| FCP — เดสก์ท็อป | 1,000 ms | 448 ms | เร็วขึ้น 2.2× |
| ข้อมูลที่ต้องโหลดก่อนเห็นหน้าแรก | 831 KB | 13 KB (29 KB ก่อนบีบ) | ลด 98% |
| JavaScript ที่เบราว์เซอร์ต้อง parse | 3,603 KB | 27 KB | ลด 99% |
| จำนวนไฟล์ที่ขอ | 12 | 5 | |
| หน่วยความจำหน้าแรก | 17 MB | 10 MB | ลด 41% |
เทียบแบบตัดตัวแปรเครือข่ายออก (ทั้งคู่เสิร์ฟจาก localhost ไม่มี gzip ไลบรารีชุดเดียวกัน) จะเห็นผลของสถาปัตยกรรมล้วน ๆ: FCP มือถือ 18,736 ms → 272 ms = เร็วขึ้น 68.9×
src/registry.js เก็บแค่ข้อมูลเครื่องมือ ไม่ import โค้ด
ไลบรารีถูกดึงตอนเปิดเครื่องมือนั้นจริงผ่าน src/loader.js (แคช promise กันโหลดซ้ำ)requestIdleCallback
ผู้ใช้ใช้เวลาจากชี้ถึงคลิกราว 100–300 ms ซึ่งพอให้โหลดล่วงหน้าได้
ตัวค้นหาก็เหมือนกัน (src/search.js กับคำค้นสำรอง src/registry-keys.js) ดึงตอนชี้หรือโฟกัสช่องค้นหา ไม่มากับหน้าแรกvendor/ มี fallback ไป CDN อัตโนมัติถ้าไฟล์หาย)scheduler.yield() (fallback setTimeout)
จอจึงไม่ค้างและ INP ไม่พุ่งแม้กำลังแปลงไฟล์ใหญ่max-age=600 เท่ากันหมดและไม่ส่ง brotli เราจึงคุมแคชเอง:
vendor/* แบบ cache-first, ที่เหลือ stale-while-revalidate → เปิดซ้ำเร็วและใช้งานออฟไลน์ได้เว็บนี้ไม่ได้คุยกับเซิร์ฟเวอร์ระหว่างแปลงไฟล์อยู่แล้ว — โค้ดทั้งหมดรันในเบราว์เซอร์ Service Worker จึงทำได้แค่เก็บ "ตัวเว็บ" ไว้ในเครื่อง แล้วหลังจากนั้นทุกอย่างทำงานได้เองโดยไม่ต้องมีเน็ต
แต่เดิมมีข้อจำกัดที่ต้องพูดตรง ๆ (พิสูจน์ด้วยการตัดเน็ตระดับเครือข่ายจริง ไม่ใช่แค่ navigator.onLine):
| สถานการณ์ | ผลจริงที่วัดได้ |
|---|---|
| เครื่องมือที่เคยเปิดตอนมีเน็ตแล้ว | ✅ ใช้ออฟไลน์ได้ |
| เครื่องมือที่ยังไม่เคยเปิดเลย | ❌ ใช้ไม่ได้ (ไลบรารียังไม่ถูกเก็บ) |
เพราะไลบรารีถูกดาวน์โหลดแบบ on-demand ตามหลัก performance ข้างบน — ตอนเปิดหน้าแรกจึงมีไลบรารีเก็บไว้ 0 ไฟล์
วิธีแก้ที่เลือกใช้: ปุ่ม "เตรียมใช้งานออฟไลน์" ท้ายหน้าแรก (src/offline.js)
กดครั้งเดียวจะดึงไลบรารี ฟอนต์ และโค้ดของทุกเครื่องมือ (~5 MB, 45 ไฟล์) มาเก็บไว้ล่วงหน้า
เลือกทำแบบให้ผู้ใช้กดเอง ไม่ใช่โหลดอัตโนมัติ เพราะการโหลด 5 MB ตั้งแต่หน้าแรกจะทำลายข้อดีเรื่องความเร็วทั้งหมด
หลังกดปุ่มแล้ว ทดสอบด้วยการตัดเน็ตจริง + เปิดเบราว์เซอร์ใหม่: Excel→PDF, PowerPoint→Word, PDF→Word และย่อรูป ใช้ได้ครบทั้งที่ไม่เคยเปิดเครื่องมือเหล่านั้นมาก่อน (8/8 ผ่าน)
ข้อจำกัดที่ยังเหลือ: OCR ครั้งแรกต้องมีเน็ต เพราะชุดภาษาไทย (~10-30 MB) โหลดจาก CDN ของ Tesseract
| กลุ่ม | เครื่องมือ |
|---|---|
| จัดหน้า PDF | จัดการหน้า PDF, รวมไฟล์ PDF, แยกไฟล์ PDF, บีบอัดไฟล์ PDF, ครอบตัดขอบ PDF, เปลี่ยนขนาดกระดาษ PDF, หลายหน้าต่อแผ่น และหนังสือเล่มเล็ก, ลบหน้าว่างจากไฟล์สแกน |
| แก้ไขและประทับตรา | แก้ไขและเซ็นบน PDF, เซ็นชื่อบน PDF, เทียบ PDF สองฉบับ, ใส่ลายน้ำ PDF, ลบชั้นที่ทับบนหน้า PDF, ใส่เลขหน้า PDF, OCR อ่านข้อความจากสแกน |
| ความปลอดภัย PDF | ใส่รหัสผ่าน PDF, ตรวจ PDF ก่อนส่ง, ลบข้อมูลลับออกจาก PDF, ปลดรหัสผ่าน PDF |
| แปลงจาก PDF | ดึงรูปออกจาก PDF, PDF เป็น PowerPoint, PDF เป็น Images, PDF เป็นภาพยาวแผ่นเดียว, PDF เป็นข้อความ, PDF เป็น Markdown, PDF เป็น Word, PDF เป็น Excel |
| รูปภาพ | แปลงชนิดไฟล์รูป, ย่อและบีบอัดรูปภาพ, ลบพื้นหลังรูปภาพ, Images เป็น PDF, สร้าง QR |
| เอกสารและจดหมายเวียน | รวมไฟล์ Word, ค้นหาและแทนที่ทั้งชุด, ตรวจเอกสารก่อนส่ง, จดหมายเวียน Word + Excel, Word เป็น PDF, ข้อความเป็น PDF |
| PowerPoint | PowerPoint เป็น Word, PowerPoint เป็น PDF |
| Excel และการคำนวณ | หายอดที่บวกกันได้เท่านี้, สลับ Excel กับ CSV, แยกไฟล์ Excel ตามคอลัมน์, รวมหลายไฟล์ Excel, ดึงข้อมูลจากอีกไฟล์มาเติม, Excel เป็น PDF |
| งานเอกสารไทย | ซ่อมไฟล์ไทยเพี้ยน, สลับปี พ.ศ. กับ ค.ศ. ทั้งคอลัมน์, ตรวจเลขบัตร ปชช. / ผู้เสียภาษี, แยกคำนำหน้า, ชื่อ, นามสกุล, แยกที่อยู่ไทยเป็นคอลัมน์, ตัวเลขเป็นบาทถ้วน / เลขไทย, นับคำภาษาไทย |
| Power BI | กราฟโดนัท Deneb, กราฟแท่งแนวนอน Deneb, กราฟ Gantt แผนงาน Deneb, ของสำเร็จรูปแจกฟรี, รายละเอียดหลายคอลัมน์ในช่องเดียวของ Matrix, สร้างธีม Power BI (theme.json), แผนที่พื้นที่รอบจุด, แผนที่การย้ายที่ตั้ง |
| Power Query | ตารางเป็นสูตร Power Query, จัดกลุ่มตัวเลขเป็นช่วง, สร้างสูตรค้นข้ามหลายแหล่ง, ยุบหลายแถวให้เหลือแถวเดียว, แปลงข้อความให้เป็นวันที่, เลือกวันล่าสุดจากหลายคอลัมน์, รวมหลาย query เป็นตัวเดียว |
| Power Automate Cloud | ตารางเป็น Schema ของ Parse JSON, ตาราง HTML สำหรับอีเมลใน flow |
ทุกเครื่องมือรองรับภาษาไทยเต็มรูปแบบ (ตรวจแล้วด้วยการเปิดไฟล์ผลลัพธ์จริง ไม่ใช่แค่ดูว่าไม่ error)
FileKit/
├── index.html หน้าเดียว + critical CSS ฝังใน (ไม่มี blocking script)
├── sw.js service worker (cache-first สำหรับ vendor)
├── manifest.webmanifest ติดตั้งเป็นแอปบนเครื่องได้
├── src/
│ ├── app.js เปลือกแอป: router + prefetch ตามเจตนา
│ ├── registry.js ทะเบียนเครื่องมือ (ข้อมูลล้วน ไม่ import โค้ด)
│ ├── registry-keys.js คำค้นสำรองของเครื่องมือ (ดึงตอนแตะช่องค้นหา)
│ ├── loader.js ตัวโหลดไลบรารีแบบ on-demand + fallback CDN
│ ├── ui.js ชิ้นส่วน UI ร่วม (dropzone, สถานะ, ปุ่ม, ช่วงหน้า)
│ ├── pdftext.js อ่านโครงบรรทัด/คอลัมน์จาก PDF (ใช้ร่วม PDF→Word/Excel)
│ ├── thaifont.js ฝังฟอนต์ไทยลง jsPDF
│ └── tools/*.js 1 ไฟล์ = 1 เครื่องมือ โหลดแยกกัน
├── vendor/ ไลบรารี self-host + ฟอนต์ไทย subset
└── assets/ CSS หน้าเครื่องมือ + ไอคอน PWA
cd FileKit && python3 -m http.server 8777
# เปิด http://127.0.0.1:8777/
ต้องเสิร์ฟผ่าน http:// (ไม่ใช่ file://) เพราะใช้ ES modules และ service worker
FileKit/ ทั้งก้อน (รวม vendor/)main / rootFlowKit วาดผังจากข้อความ เคยอยู่ที่ flow/ ตอนนี้อยู่ที่ https://patcharasitp.github.io/flowkit/ (repo flowkit)
flow/index.html ที่เหลือเป็นหน้าส่งต่อ พาลิงก์เดิมไปหน้าวาดใหม่พร้อม ? และ # ครบ
‼️ FlowKit ยัง import ไฟล์กลางของเราตรง ๆ (src/i18n.js , src/handoff.js , src/inapp.js , ฟอนต์ Sarabun)
แก้ไฟล์พวกนี้แล้วต้องรัน tests/runp.sh contract ก่อนปล่อยของทุกครั้ง (อยู่ใน runp.sh all แล้ว ต้องมีโฟลเดอร์ FlowKit ข้าง ๆ)
เปิด https://patcharasitp.github.io/filekit/go/?ชื่อลิงก์ แล้วหน้าเว็บพาไปที่ลิงก์เต็ม ใช้ได้กับลิงก์ทุกแบบ ไม่ต้องพึ่งลิงก์ย่อของบริการไหน
สร้างลิงก์เองที่ https://patcharasitp.github.io/filekit/go/new/ วางลิงก์ยาว กดย่อ ได้ลิงก์สั้นทันที ต้องวาง fine-grained token ที่เขียนได้เฉพาะรีโป golinks ทุกครั้งที่เปิดหน้า
ข้อมูลลิงก์อยู่รีโป golinks เข้ารหัสด้วย AES-GCM กุญแจมาจากชื่อลิงก์ผ่าน PBKDF2 ในรีโปจึงไม่มีทั้งชื่อลิงก์และปลายทางแบบอ่านออก
หน้าพาไปอ่านไฟล์ผ่าน raw.githubusercontent.com ลิงก์ใหม่จึงใช้ได้ทันทีโดยไม่ต้องรอ FileKit ขึ้นเว็บใหม่ ลิงก์ที่แก้ปลายทางอาจใช้เวลาไม่เกิน 5 นาที
แกนกลางอยู่ที่ go/core.js ไฟล์เดียว ใช้ทั้งหน้าพาไป หน้าสร้างลิงก์ และ tools/golink.mjs ฝั่งเครื่อง
service worker ปล่อยทุกอย่างใต้ go/ ไปถามเครือข่ายตรง เทสอยู่ที่ tests/golink.test.mjs กับ tests/browser_golink.py
กติกาความปลอดภัยจากรีวิวพี่ปริม 24/09/2026 (.claude/agent-progress/golink-selfserve-security.md ในโฟลเดอร์งาน) ห้ามถอยทีละข้อ
go/core.js (เก็บเป็นแฮช) นอกนั้นโชว์ชื่อโดเมนให้กดเอง ลิงก์ที่มีชื่อผู้ใช้ในตัวถูกปฏิเสธnode tools/golink.mjs check --live ตรวจให้ทุกครั้ง/tmp/.../e2e.py อัปโหลดไฟล์จริง กดปุ่มจริง ดาวน์โหลดผลลัพธ์จริง แล้วเปิดไฟล์ตรวจเนื้อใน
(PDF ตรวจว่ามีอักษรไทยกี่ตัว · XLSX/DOCX เปิดอ่านค่าจริง · ZIP ตรวจรายชื่อไฟล์ข้างใน)
ผลล่าสุด: 16/16 ผ่าน ทั้งบนเครื่อง และรันซ้ำบน production URL จริง (15/15 + OCR ทดสอบแยก)
ไฟล์ที่ดาวน์โหลดจาก production ถูกเปิดตรวจเนื้อในครบทุกไฟล์ — ภาษาไทยอยู่ครบ 15/15
ผู้ใช้เอาไฟล์ PowerPoint ใส่เครื่องมือ PDF→Word แล้วได้ข้อความว่า "ไฟล์นี้ไม่ใช่ PDF ที่ถูกต้อง หรือไฟล์เสียหาย" ซึ่งทำให้เข้าใจผิดว่าไฟล์ตัวเองพัง ทั้งที่ไฟล์ปกติดี แค่มาผิดเครื่องมือ — จากเคสเดียวนี้แก้ไป 6 เรื่อง:
src/filetype.js) — บอกว่าไฟล์นี้คืออะไร และมีปุ่มพาไปเครื่องมือที่ถูกให้เลยNo password given เป็นภาษาอังกฤษดิบและไปต่อไม่ได้
ตอนนี้มีช่องใส่รหัสในหน้าเลย (src/pdfopen.js เป็นประตูเดียวที่ทุกเครื่องมือใช้)src/ocr.js, โหลด Tesseract เมื่อกดปุ่มเท่านั้น)notesSlide ไม่ตรงกับเลขสไลด์ ต้องตามลิงก์ใน _rels เท่านั้นฟีเจอร์นี้เอาข้อมูลจาก Excel เติมลงเทมเพลต Word ทีละแถว ได้เอกสารครบทั้งชุดในครั้งเดียว งานลักษณะนี้มักมีข้อมูลอ่อนไหว (ชื่อ เงินเดือน เลขบัตรประชาชน) การทำในเบราว์เซอร์จึงได้เปรียบชัดเจน
ใช้ easy-template-x (MIT) ที่ bundle เองไว้ใน vendor/ — เลือกตัวนี้เพราะ license สะอาดล้วน
ไม่มีฟีเจอร์ที่ต้องจ่ายเงินแม้แต่การแทรกรูป (ต่างจาก docxtemplater ที่ image/HTML/chart module เสียเงิน)
และพึ่ง JSZip เวอร์ชันเดียวกับที่โปรเจกต์นี้มีอยู่แล้ว
ไลบรารีเผยแพร่เป็น ESM ที่มี bare import ซึ่งเบราว์เซอร์แก้เองไม่ได้ จึง bundle ด้วย esbuild
พร้อมแทน @xmldom/xmldom ด้วย DOMParser ของเบราว์เซอร์ และแทน jszip ด้วยตัวที่โหลดไว้แล้ว
→ เหลือ 33 KB (gzip) จาก 85 KB
กับดักหลักคือ Word ไม่ได้เก็บข้อความเป็นก้อนเดียว — ย่อหน้าหนึ่งถูกหั่นเป็นหลาย <w:r> (run)
ตามการจัดรูปแบบ การตรวจคำสะกด และประวัติการแก้ไข ตัวยึด {{ชื่อ}} ที่คนพิมพ์ติดกันบนหน้าจอ
จึงอาจกลายเป็น {{ชื่ กับ อ}} คนละ run ในไฟล์จริง โค้ดที่ค้นหาทีละ run จะหาไม่เจอเลย
ตอนแรกเขียน engine เองและใช้งานได้จริง (ต่อข้อความทุก run เป็นสตริงเดียวก่อนค้นหา) แต่ทำ ตารางวนซ้ำ ไม่ได้ ซึ่งเอกสารจริงเกือบทุกใบต้องใช้ — ใบเสนอราคา ใบเสร็จ ใบส่งของ ล้วนมีรายการหลายบรรทัด จึงเปลี่ยนมาใช้ไลบรารีที่จัดการเรื่องนี้ครบแล้ว
ทดสอบด้วยเคสที่หั่น run จริง: สร้างไฟล์ทดสอบที่หั่นทุก 7 ตัวอักษรจนตัวยึด 7 จาก 8 ตัวถูกตัดกลาง แล้วยืนยันว่ายังหาเจอครบและแทนที่ถูกต้อง โดยรูปแบบตัวอักษรเดิม (ตัวหนา) ยังอยู่
สองโหมดการใช้งาน
| โหมด | ใช้เมื่อไร | ตัวอย่าง |
|---|---|---|
| หนึ่งแถว = หนึ่งเอกสาร | ข้อมูลหนึ่งคนอยู่ในแถวเดียว | หนังสือรับรอง ป้ายชื่อ จดหมายเวียน |
| รวมหลายแถวเป็นเอกสารเดียว | เอกสารหนึ่งใบมีรายการหลายบรรทัด | ใบเสนอราคา ใบเสร็จ ใบส่งของ |
โหมดที่สองใช้กับเทมเพลตที่มีบล็อกวนซ้ำ {{#รายการ}} … {{/รายการ}} ในแถวตาราง
ระบบจัดกลุ่มแถวที่มีค่าตรงกัน (เช่นเลขที่ใบเสนอราคาเดียวกัน) ให้เป็นเอกสารเดียว
และเดาโหมดให้อัตโนมัติเมื่อพบว่าเทมเพลตมีบล็อกวนซ้ำและข้อมูลมีค่าซ้ำในคอลัมน์แรก
| เครื่องมือ | แก้ปัญหาอะไร | จุดที่ยาก |
|---|---|---|
| รวมไฟล์ Word | รวมรายงานจากหลายคนเป็นเล่มเดียว | รหัสอ้างอิงรูป (rId) ของแต่ละไฟล์ซ้ำกันหมด ถ้าต่อดื้อ ๆ รูปในไฟล์ที่สองจะกลายเป็นรูปของไฟล์แรก — ต้องออกรหัสใหม่และย้ายไฟล์รูปพร้อมตั้งชื่อใหม่ทั้งชุด |
| ค้นหา–แทนที่ทั้งชุด | เปลี่ยนชื่อบริษัท/ปี ในเอกสารหลายสิบไฟล์ | คำที่ค้นอาจถูก Word หั่นคาไว้คนละท่อน ต้องต่อข้อความทั้งย่อหน้าก่อนค้น · \b ใช้กับภาษาไทยไม่ได้ จึงบังคับ "ทั้งคำ" เฉพาะเมื่อเป็นอักษรละติน |
| ตรวจเอกสารก่อนส่ง | คอมเมนต์ ประวัติแก้ไข และชื่อผู้เขียนที่ติดไปกับไฟล์ | ลบไฟล์คอมเมนต์อย่างเดียวไม่พอ ต้องตัดความสัมพันธ์ใน _rels และ [Content_Types].xml ด้วย ไม่งั้น Word แจ้งว่าไฟล์เสีย · การยอมรับการแก้ไขต้องลบ <w:del> ทั้งก้อนก่อน แล้วค่อยถอดเปลือก <w:ins> ไม่งั้นข้อความที่ถูกลบจะหลุดกลับมา |
| Word → PDF หลายไฟล์ | แปลงทั้งโฟลเดอร์ในครั้งเดียว | ไฟล์ที่พังหนึ่งไฟล์ต้องไม่ทำให้ทั้งชุดล้ม — รายงานเป็นรายไฟล์แล้วทำต่อ |
ทำไมเครื่องมือ "ตรวจก่อนส่ง" ถึงเหมาะกับเว็บที่ทำงานในเครื่องเป็นพิเศษ: ไฟล์ที่กลัวข้อมูลรั่วมากที่สุด ย่อมไม่ควรถูกอัปโหลดขึ้นเว็บใครเพื่อ "ล้างข้อมูล" — เว็บอื่นที่ทำเรื่องนี้ได้ล้วนต้องรับไฟล์ขึ้นเซิร์ฟเวอร์ก่อน ซึ่งขัดกับเหตุผลที่คนใช้มันตั้งแต่แรก
โจทย์กระทบยอดที่เจอทุกเดือน: เงินโอนเข้าก้อนเดียว 257,425.30 แต่ในระบบเป็นใบเล็ก ๆ หลายใบ ต้องหาว่าใบไหนบ้างรวมกันได้พอดี Excel มี Solver มาให้อยู่แล้ว จึงลองวัดของจริงก่อนตัดสินใจเขียนเอง (รันผ่าน Excel COM บนเครื่องจริง 15 ก.ย. 2569 ทุกบรรทัดคือเวลาที่จับได้จริง)
| จำนวนตัวเลข | Solver ของ Excel | เครื่องมือนี้ |
|---|---|---|
| 12 | 0.84 วินาที ตอบถูก | ต่ำกว่า 1 ms |
| 120 | 0.88 วินาที | ต่ำกว่า 1 ms |
| 200 | 1.37 วินาที | ต่ำกว่า 1 ms |
| 50 (บางเป้าหมาย) | ไม่คืนคำตอบเลยจน 4 นาที ต้องฆ่าโปรเซสทิ้ง | ต่ำกว่า 1 ms |
| 400 | ปฏิเสธทันที เพดานตัวแปร 200 ตัว | 2 ms |
| 14,651 (ไฟล์งานจริง) | ใส่ไม่ได้ตั้งแต่ต้น | 46 ms |
สองบรรทัดที่สำคัญที่สุดคือแถว 50 กับแถว 400 บรรทัดแรกบอกว่าเวลาของ Solver เดาไม่ได้ ข้อมูลชุดเดียวกัน เป้าหมายหนึ่งจบใน 1.2 วินาที อีกเป้าหมายไม่จบเลย ส่วนบรรทัดหลังคือเพดานแข็ง Solver รุ่นที่ติดมากับ Excel รับตัวแปรได้ 200 ตัว ไฟล์หลักหมื่นแถวจึงไม่มีทางใส่เข้าไปได้
และต่อให้ Solver ตอบได้ มันคืนคำตอบเดียวแล้วจบ ไม่บอกว่ามีกี่ชุดที่รวมกันได้เท่ากัน ทั้งยังไม่เลือกชุดที่ใช้ใบน้อยที่สุดให้ (ทดลองซ่อนคำตอบ 4 ใบไว้ Solver ตอบกลับมา 8 ถึง 12 ใบ) ซึ่งเป็นจุดที่อันตรายที่สุดของโจทย์นี้ เพราะ คำตอบแทบไม่เคยมีชุดเดียว ไฟล์จริงชุดนั้น ถ้าให้ใช้ไม่เกิน 3 ใบ มีถึง 73 ชุดที่รวมกันได้พอดี เครื่องมือนี้จึงโชว์หลายชุดเรียงจากใบน้อยไปมาก และเขียนไว้ตรง ๆ ว่าเจอกี่ชุด กับค้นครบทุกความเป็นไปได้แล้วหรือยัง
หน้านี้ยังมีแท็บ "ทำเองใน Excel" ที่สร้างขั้นตอน Solver ให้ตามข้อมูลที่เปิดอยู่จริง
(ช่วง SUMPRODUCT, ช่วงตัวแปร, ข้อจำกัด bin) สำหรับคนที่อยากทำในไฟล์ของตัวเอง
และมีปุ่ม ดาวน์โหลดไฟล์ Excel ที่ตั้ง Solver ไว้ให้แล้ว ซึ่งเปิดใน Excel แล้วกด Data > Solver > Solve
ได้ทันทีโดยไม่ต้องกรอกอะไรเลย เพราะการตั้งค่าของ Solver ไม่ได้อยู่ที่ไหนลึกลับ มันคือ
ชื่อที่นิยามระดับชีต (solver_opt, solver_adj, solver_typ, solver_val, solver_eng, solver_relN)
ที่เขียนลงไฟล์เองได้ วิธีหาคือให้ Excel จริงกด SolverSave แล้วดัมพ์ชื่อออกมาดู
ไฟล์ที่เว็บสร้างจึงพาการตั้งค่าไปด้วย ทดสอบกับ Excel จริงแล้วได้คำตอบใน 0.82 วินาที (return code 14)
โดยไม่ต้องแตะ Solver สักช่อง ไฟล์นี้ใส่ได้มากสุด 200 แถวตามเพดานตัวแปร และ ยกแถวที่เป็นคำตอบขึ้นก่อน
เพื่อให้กด Solve แล้วเจอคำตอบแน่นอน ไม่ใช่ตัด 200 แถวแรกมาแบบสุ่ม
กับดักสองข้อที่เจอตอนทำ และตอนนี้มีเทสยืนที่ tests/browser_matchsum.py กันไว้แล้ว:
blankrows:false แถวที่ทั้งแถวอ่านไม่ได้
(ไฟล์จริงมี #N/A อยู่ 5 แถว) จึงหลุดไปทั้งแถว ทำให้ "แถว 14591" กลายเป็น "แถว 14586"
งานกระทบยอดต้องเปิดไฟล์ไปดูแถวนั้นต่อ เลขแถวผิดคือผิดทั้งงาน และผิดแบบเงียบวาดลายเซ็นด้วยเมาส์หรือนิ้ว (หรืออัปโหลดรูปลายเซ็นที่สแกนไว้) แล้วคลิกวางบนเอกสาร
ลากย้าย ปรับขนาด วางได้หลายจุดหลายหน้า · ลายเซ็นถูกเก็บใน localStorage ของเครื่องผู้ใช้เพื่อใช้ซ้ำ
ทำไมต้องทำในเบราว์เซอร์: เอกสารที่ต้องเซ็นคือสัญญา ใบลา ใบเบิกเงิน หนังสือมอบอำนาจ — การอัปโหลดของพวกนี้ขึ้นเว็บของใครไม่รู้เพื่อ "เซ็น" คือความเสี่ยงที่คนมักไม่ทันคิดถึง
รายละเอียดที่ต้องจัดการ
y = ความสูงหน้า − (สัดส่วน × ความสูงหน้า) − ความสูงลายเซ็น และเก็บตำแหน่งเป็นสัดส่วน 0–1
เพื่อให้ไม่ขึ้นกับขนาดที่แสดงบนจอmax-height: 68vh ให้เห็นทั้งหน้าในครั้งเดียว‼️ นี่คือลายเซ็นแบบภาพวางทับ (เหมือนเซ็นแล้วสแกน) ไม่ใช่ลายเซ็นดิจิทัลที่มีใบรับรอง
.doc / .ppt รุ่นเก่ายังไม่รองรับ (ต้องบันทึกเป็น .docx / .pptx ก่อน)repo นี้เปิดให้อ่านโค้ดได้ แต่ ไม่ได้ให้สัญญาอนุญาตโอเพนซอร์ส (ไม่มีไฟล์ LICENSE = สงวนสิทธิ์ทั้งหมดตามกฎหมายลิขสิทธิ์) ใช้งานเว็บได้ฟรีไม่จำกัด อ่านและเรียนรู้จากโค้ดได้ แต่การคัดลอกทั้งชุดไปเผยแพร่ต่อในชื่ออื่นไม่ได้
เหตุผลที่เลือกทางนี้ ไม่ใช่ MIT หรือ AGPL
กติกาที่ตามมา ห้ามลืม: ตอนทำฟีเจอร์ที่เว็บ AGPL มีอยู่แล้ว ห้ามเปิดโค้ดของเขาดู ดูได้แค่ "รายการฟีเจอร์"
กับหน้าจอที่ผู้ใช้เห็น แล้วเขียนเองทั้งหมด (ไลบรารีที่ยืมมาใช้ทุกตัวเป็น MIT / Apache / BSD ยกเว้น libheif ที่เป็น LGPL
ซึ่งเราลิงก์แบบไดนามิกตามเงื่อนไข ดู vendor/NOTICE.md)
FileKit เก็บไลบรารีทุกตัวไว้ในเครื่องเรา ไม่ดึงจาก CDN ตอนผู้ใช้ใช้งาน
เครดิตและสัญญาอนุญาตของแต่ละตัวอยู่ที่ vendor/NOTICE.md
‼️ ตัวที่ต้องระวังเป็นพิเศษคือ libheif (ตัวถอดรูป HEIC ของ iPhone) ซึ่งเป็น LGPL-3.0 ต่างจากตัวอื่นที่เป็น MIT/Apache/BSD · เงื่อนไขและวิธีที่เราทำตามอยู่ในไฟล์นั้น