Excel - Người Bạn Không Thể Rời Của Các Nhà Thiết Kế Trò Chơi
Tôi tin rằng ít nhất trong cộng đồng thiết kế game tại Việt Nam, Excel giống như “người bạn tri kỷ” không thể thiếu mỗi ngày. Không chỉ dừng lại ở việc lập bảng số liệu, mà gần như mọi tài liệu cuối cùng đều được viết dưới dạng Excel. Là một lập trình viên, tôi có chút ác cảm với định dạng Excel - giống như thời tôi ghét Word vì tính bất tiện. Đáng lý những tài liệu chỉ vài dòng chữ nên lưu ở định dạng đơn giản hơn, nhưng giờ đây thay vì dùng Word, mọi người đều chuyển sang Excel. Nếu có thể, các nhà thiết kế sẵn sàng viết script trong từng ô dữ liệu với việc đánh dấu trọng tâm bằng màu đỏ.
Việc trích xuất thông tin văn bản từ Excel không hề phức tạp, nhưng vấn đề nằm ở sự “khó tính” của định dạng này với các công cụ kiểm soát phiên bản. Thử tưởng tượng, chỉ cần mở và lưu lại file Excel thôi cũng có thể sinh ra phiên bản hoàn toàn mới. Lý do nằm ở việc file chứa các dữ liệu như thời gian sửa đổi cuối cùng (Excel không tin vào thông tin thời gian của hệ thống file), hay vị trí ô dữ liệu cuối cùng được kích hoạt. Trong môi trường làm việc nhóm như vậy, việc kiểm soát phiên bản gần như là “địa ngục”.
Tôi đã dành khoảng một tuần để giải quyết hàng loạt vấn đề này. Kết quả không đến nỗi thất bại hoàn toàn nhưng cũng chưa thể gọi là thành công. Hãy cùng điểm qua những “bẫy” tôi đã gặp phải tuần trước.
Bối cảnh vấn đề
Trong dự án của chúng tôi, các nhà thiết kế lưu trữ mọi thứ họ tạo ra trong hàng loạt bảng Excel. Cũng giống như các lập trình viên thế hệ trước, mỗi người tự quản lý “mảnh đất” file riêng của mình. Dù sử dụng công cụ kiểm soát phiên bản, sự xung đột gần như không xảy ra. Tuy nhiên, 1% trường hợp đặc biệt vẫn tồn tại - khi nhiều người sửa cùng một bảng, đặc biệt là trong giai đoạn gấp gáp khi cả lập trình viên cũng phải chỉnh sửa dữ liệu trực tiếp trong Excel. Việc di chuyển từ SVN sang Git càng làm phức tạp thêm, bởi quy trình làm việc của Git vượt quá khả năng tiếp nhận của đa số nhà thiết kế (thực tế họ chỉ cần một công cụ sao lưu phiên bản đơn giản, vì định dạng Excel vốn không hỗ trợ nhiều tính năng khác).
Giải pháp ban đầu
Tôi nhận ra rằng file .xlsx thực chất là một file zip chuẩn chứa các file XML bên trong. Nếu chỉ cần một định dạng văn bản thuần, giải pháp đơn giản là giải nén và đóng gói lại ở dạng không nén. Đối với hình ảnh nhúng, chỉ cần mã hóa base64 vì chúng ít bị thay đổi. Ban đầu tôi nghĩ việc này chỉ cần 2 tiếng, nhưng thực tế chứng minh tôi đã quá lạc quan!
Tôi đã viết một chương trình nhỏ bằng Lua để đọc các file trong zip, sắp xếp tên file, sau đó nối chúng lại thành một file văn bản lớn với nội dung nhị phân được mã hóa base64. Để hỗ trợ kiểm soát phiên bản tốt hơn, tôi thêm các ký tự xuống dòng vào các thẻ XML. Như vậy, công cụ quản lý phiên bản có thể dễ dàng theo dõi sự khác biệt giữa các phiên bản.
Loại bỏ dữ liệu vô nghĩa
Bước tiếp theo là loại bỏ các đoạn dữ liệu gây chênh lệch phiên bản nhưng không quan trọng như thời gian sửa đổi cuối cùng hay vị trí ô kích hoạt. Nhờ đó, việc lưu file sau khi mở sẽ không tạo ra sự khác biệt. Tuy nhiên, làm cách nào để Excel (hoặc WPS) vẫn có thể mở và chỉnh sửa định dạng mới này?
Tôi chọn giải pháp “vòng vo”: Viết script tạo thư mục/file tạm thời. Khi người dùng mở file định dạng tùy chỉnh, script sẽ chuyển sang file xlsx tạm thời tiêu chuẩn để phần mềm liên kết (Excel/WPS) chỉnh sửa. Hệ thống sẽ theo dõi thời gian sửa đổi để chuyển ngược lại. Khi file tạm thời được ghi dữ liệu mới, script sẽ xóa file tạm đó. Với 10 dòng Lua, định dạng mới có thể tích hợp dễ dàng vào hệ thống.
Những thử thách phát sinh
Thực tế sử dụng cho thấy một vấn đề nghiêm trọng: Nhà thiết kế thường nhúng các đối tượng OLE như sơ đồ Visio yêu thích. Các đối tượng OLE này chứa dữ liệu nhị phân với chuỗi timestamp ẩn bên trong, khiến nội dung không thay đổi vẫn bị coi là khác biệt. Giải pháp nằm ở việc dùng 7zip - phần mềm có thể giải nén các đối tượng COM. Chỉ với vài chục dòng C, tôi viết chương trình loại bỏ timestamp trong các đối tượng này.
Định dạng văn bản tùy chỉnh
Không dừng lại ở đó, tôi quyết định thiết kế một định dạng mới ưu việt hơn CSV. Định dạng này giữ lại các định dạng bảng cơ bản (chiều rộng/cao ô, màu sắc, đường viền…) nhưng có thể chỉnh sửa dễ dàng bằng text editor. Cấu trúc dữ liệu được chia rõ ràng:
|
|
Phần [data] chứa công thức, [value] lưu giá trị tính toán và [style] quản lý định dạng. Ngay cả khi phần style bị hỏng, file vẫn có thể mở lại bằng Excel. Định dạng này đặc biệt hữu ích với lập trình viên Linux vốn không muốn cài Excel.
Bài học rút ra
Tôi nhận ra rằng việc tái tạo đầy đủ các định dạng trong Excel đòi hỏi hiểu biết cực kỳ sâu về cấu trúc file ISO-IEC-29500-1. Vì vậy, tôi quyết định không công bố công cụ này mà chỉ chia sẻ một sản phẩm phụ - công cụ xlsx2txt trên GitHub giúp tìm kiếm dữ liệu trong Excel từ command line.
Một số kinh nghiệm bổ ích
Trong quá trình nghiên cứu, tôi đã kiểm tra nhiều thư viện xử lý xlsx ở các ngôn ngữ Go, Python, Lua. Đặc biệt với Lua, thư viện xlsxwriter có tiềm năng cải thiện hiệu năng lớn. Ví dụ, hàm escape ký tự có thể tối ưu từ:
|
|