Hệ thống E-Form cho phép:
- Upload template Word (.docx) với các biến dynamic
- Tự động phát hiện và cấu hình các biến trong template
- Tạo form điền thông tin dựa trên template
- Load dữ liệu từ API backend
- Sử dụng POI-TL để xử lý template Word
- Xuất PDF từ form đã điền
# Tạo thư mục project
mkdir eform-backend
cd eform-backend
# Copy các file đã tạo vào thư mục src/main/java/com/example/eform/
eform-backend/
├── src/
│ └── main/
│ ├── java/
│ │ └── com/
│ │ └── example/
│ │ └── eform/
│ │ ├── EFormApplication.java
│ │ ├── controller/
│ │ │ └── EFormController.java
│ │ ├── dto/
│ │ │ └── (các DTO classes)
│ │ ├── model/
│ │ │ └── (các Entity classes)
│ │ ├── repository/
│ │ │ └── (các Repository interfaces)
│ │ └── service/
│ │ └── EFormService.java
│ └── resources/
│ └── application.properties
├── uploads/ # Thư mục lưu template
├── outputs/ # Thư mục tạm cho PDF
└── pom.xml
# Cài đặt dependencies
mvn clean install
# Chạy ứng dụng
mvn spring-boot:run
Backend sẽ chạy trên http://localhost:8080
# Tạo project React
npx create-react-app eform-frontend
cd eform-frontend
# Cài đặt dependencies
npm install lucide-react axios
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Copy nội dung từ file tailwind.config.js
đã tạo
Copy nội dung từ React component đã tạo vào src/App.js
Copy nội dung CSS vào src/index.css
npm start
Frontend sẽ chạy trên http://localhost:3000
Tạo file Word (.docx) với các biến theo format:
{{tenBien}}
cho text đơn giản{{nguoiNhan}}
cho tên người nhận{{ngayThang}}
cho ngày tháng{{diaChi}}
cho địa chỉ
Ví dụ template:
CÔNG TY {{tenCongTy}}
Địa chỉ: {{diaChi}}
Điện thoại: {{dienThoai}}
Kính gửi: {{nguoiNhan}}
Ngày: {{ngayThang}}
Nội dung: {{noiDung}}
Trân trọng,
{{nguoiKy}}
- Mở ứng dụng web
- Chọn tab "Templates"
- Kéo thả hoặc click để chọn file Word
- Nhập tên template
- Hệ thống sẽ tự động phát hiện các biến
- Trong danh sách templates, click "Tạo Form"
- Nhập tên form
- Điền thông tin cho các biến
- Click "Lưu Form"
- Chọn tab "Forms"
- Tìm form cần xuất
- Click "PDF" để tải xuống file PDF
POST /api/v1/templates/upload
- Upload templateGET /api/v1/templates
- Lấy danh sách templatesGET /api/v1/templates/{id}
- Lấy chi tiết template
POST /api/v1/forms
- Lưu formGET /api/v1/forms
- Lấy danh sách formsGET /api/v1/forms/{id}
- Lấy chi tiết formPOST /api/v1/forms/generate-pdf
- Tạo PDF từ dữ liệuPOST /api/v1/forms/{id}/generate-pdf
- Tạo PDF từ form đã lưu
CREATE TABLE templates (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
filename VARCHAR(255) NOT NULL,
file_path VARCHAR(500) NOT NULL,
variables TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
CREATE TABLE forms (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
template_id BIGINT NOT NULL,
name VARCHAR(255) NOT NULL,
form_data TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (template_id) REFERENCES templates(id)
);
Tạo template với bảng có thể lặp:
{{#employees}}
STT | Họ tên | Chức vụ | Lương
{{index}} | {{name}} | {{position}} | {{salary}}
{{/employees}}
Xử lý trong Spring Boot:
public class EmployeeData {
private List<Employee> employees;
public static class Employee {
private String name;
private String position;
private String salary;
// getters/setters
}
}
Template với điều kiện:
{{#isManager}}
Phần dành cho quản lý: {{managerContent}}
{{/isManager}}
{{^isManager}}
Phần dành cho nhân viên: {{employeeContent}}
{{/isManager}}
Thêm hình ảnh vào template:
@Service
public class ImageService {
public PictureRenderData createPicture(String imagePath) {
return Pictures.ofLocal(imagePath)
.size(100, 100)
.create();
}
}
const validateForm = (formData, template) => {
const errors = {};
template.variables.forEach(variable => {
if (variable.required && !formData[variable.name]) {
errors[variable.name] = 'Trường này là bắt buộc';
}
if (variable.type === 'email' && formData[variable.name]) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(formData[variable.name])) {
errors[variable.name] = 'Email không hợp lệ';
}
}
});
return errors;
};