Beberapa waktu lalu, saya menerima permintaan aplikasi web untuk menghasilkan Word secara otomatis. Sekarang saya telah mengumpulkan beberapa langkah penting untuk dibagikan.
Ide: (Catatan: Ini hanya untuk versi WORD2003, versi lain serupa.)
Karena data internal dan format file WORD disimpan dalam bentuk file XML, file WORD dapat dengan mudah dikonversi dari format DOC ke XML, dan jauh lebih nyaman untuk mengoperasikan file XML, sehingga mewujudkan integrasi dengan Berbagai operasi platform-independen menghasilkan file Word melalui kueri simpul, penggantian, penghapusan, penambahan, dll. Oleh karena itu, inti dari pembuatan file WORD berdasarkan template adalah proses penggantian tag khusus pada file XML dengan data pengguna kemudian disimpan sebagai file DOC.
Berikut adalah beberapa langkah penting yang terlibat (mengambil surat pengantar sebagai contoh)
Langkah pertama: Buatlah template WORD sesuai kebutuhan Anda
Buat file WORD baru dalam format DOC, isi konten template sesuai kebutuhan, dan atur format template, termasuk font, gaya, baris kosong, dll. Gunakan tag khusus (seperti: [※Nama Unit※]) untuk isi terlebih dahulu data yang perlu diisi bit, lalu simpan file WORD yang baru dibuat sebagai file berformat XML. Dengan demikian, template WORD sudah selesai, kodenya adalah sebagai berikut:
Tambahkan file konfigurasi baru bernama template-rule.xml, setiap node templat sesuai dengan jenis templat. Terdapat taglist node di setiap template. Semua node anak yang terdapat di node ini berisi informasi tentang semua node yang akan diganti atau dihapus di template. Informasi node tersebut meliputi: nilai node, atribut node Nama Inggris, deskripsi bahasa Mandarin, jenis bidang, apakah bisa dihapus, dll. Saat mengatur file konfigurasi ini, perlu diperhatikan bahwa nilai atribut desc harus konsisten dengan placeholder di template XML. Misalnya: item input tahun [※Tahun※] yang ditetapkan dalam templat XML harus sesuai dengan nama desc="Tahun" di template-rule.xml. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
<!--?xml versi="1.0" pengkodean="GB2312"?-->
<!-- Definisi templat-->
<templat>
<!-- Deskripsi: S-string; D-date; E-amount; M-uppercase amount; ifEmptyDelete: T-value kosong untuk menghapus node induk, defaultnya adalah F -->
<template name="RECOMMEND-LETTER" desc="Surat Pengantar" templatefile="template4.xml">
<taglist comment="Daftar tag nilai tunggal">
<tag id="1" name="ToPartment" desc="Departemen Penerima" type="S" ifemptydelete="T">#ToPartment</tag><!--Departemen Penerima-->
<tag id="2" name="OwnerName" desc="Name" type="S">#OwnerName</tag><!--Nama-->
<tag id="3" name="CountNum" desc="Jumlah orang" type="S">#CountNum</tag><!--Jumlah orang-->
<tag id="4" name="Bisnis" desc="Content" type="S">#Bisnis</tag><!--Konten-->
<tag id="5" name="UsefulDays" desc="Validity period" type="S">#UsefulDays</tag><!--Masa berlaku-->
<tag id="6" name="Tahun" desc="tahun" type="S">#Tahun</tag><!--tahun-->
<tag id="7" name="Bulan" desc="bulan" type="S">#Bulan</tag><!--bulan-->
<tag id="8" name="Hari" desc="日" type="S">#Hari</tag><!--Hari-->
</daftar tag>
</templat>
</templat>
Langkah 3: Tulis kode Java
Copy kode kodenya sebagai berikut:
/**
* Parameter dan aturan
*/
Aturan kelas publikDTO {
/**
* nama tag
*/
String pribadi parmName;
/**
* deskripsi tag
*/
String pribadi parmDesc;
/**
* tandai nomor seri
*/
String pribadi parmSeq;
/**
* jenis nilai tag
*/
tipe parm String pribadi;
/**
* nama parameter tag
*/
string pribadi parmReguler;
/**
* nilai tanda
*/
String pribadi parmValue;
/**
* Jika nilai tag kosong, hapus atribut ini
*/
String pribadi ifEmptyDelete;
}
Copy kode kodenya sebagai berikut:
/**
* Deskripsi: Informasi templat Word
*/
Templat kelas publik {
nama String pribadi;//nama templat
deskripsi String pribadi;//deskripsi template
File templat String pribadi;//file templat
aturan<ruledto> Vektor pribadi;//aturan templat
}</ruledto>
Copy kode kodenya sebagai berikut:
WordBuilder kelas publik {
/**
* Baca aturan penggantian berdasarkan template
* @param templateName ID templat
*/
@SuppressWarnings("tidak dicentang")
templat publik loadRules(Peta<string, string=""> ruleValue) {
InputStream di = null;
Templat templat = Templat baru();
// Jalur file konfigurasi aturan
String ruleFile = "template-rule.xml";
// Nama aturan templat
String templatRuleName = "";
mencoba {
templateRuleName = ruleValue.get("ruleName");
//Baca file aturan template
di = ini.getClass().getClassLoader().getResourceAsStream(ruleFile);
// Mengurai aturan templat
SAXBuilder sb = SAXBuilder baru();
Dokumen doc = sb.build(in);
Elemen root = doc.getRootElement(); // Dapatkan elemen root
Daftar<elemen> templateList = root.getChildren();//Semua konfigurasi templat
Elemen elemen = null;
Aturan vektor<ruledto> = null;
for (int i = 0; i < templateList.size(); i++) {// Melintasi semua template
elemen = (Elemen) templateList.get(i);
String templateName = elemen.getAttributeValue("nama");
if (templateRuleName.equalsIgnoreCase(templateName)) {//Temukan konfigurasi template yang diberikan
templat.setName(templateName);
template.setDesc(element.getAttributeValue("desc"));
template.setTemplateFile(elemen
.getAttributeValue("templateFile"));
Daftar<elemen> tagList = ((Elemen) elemen.getChildren()
.get(0)).getChildren(); // daftar tag
Tag elemen = null;
AturanDTO aturanDTO = null;
aturan = Vektor baru<ruledto>();
untuk (int j = 0; j < tagList.ukuran(); j++) {
tag = (Elemen) tagList.get(j);
ruleDTO = AturanDTO baru();
ruleDTO.setParmName(tag.getAttributeValue("nama"));
ruleDTO.setParmDesc("【※"
+ tag.getAttributeValue("desc") + "※】");
ruleDTO.setParmSeq(tag.getAttributeValue("id"));
ruleDTO.setParmType(tag.getAttributeValue("type"));
if ("T".equalsIgnoreCase(tag
.getAttributeValue("ifEmptyDelete"))) {// Apakah tanda dapat dihapus
ruleDTO.setIfEmptyDelete("T");
} kalau tidak {
ruleDTO.setIfEmptyDelete("F");
}
ruleDTO.setParmRegular(tag.getText());
// nilai
// Tentukan tipe parameter
Nilai string = (String) ((Peta<string, string="">) ruleValue)
.get(ruleDTO.getParmRegular().replaceAll("#",
""));
ruleDTO.setParmValue(nilai);
aturan.tambahkan(ruleDTO);
}
templat.setRules(aturan);
merusak;
}
}
} tangkapan (FileNotFoundException e) {
e.printStackTrace();
} tangkapan (JDOMException e) {
e.printStackTrace();
} tangkapan (IOException e) {
e.printStackTrace();
} Akhirnya {
mencoba {
melampirkan();
} tangkapan (Pengecualian e) {
e.printStackTrace();
}
}
templat pengembalian;
}
/**
* Temukan simpul induk
*/
Elemen publik findElement(Elemen currNode, String parentNodeId) {
//Node ditandai sebagai kosong
if (currNode == null || parentNodeId == null) {
kembalikan nol;
}
Elemen pNode = nol;
Mengerjakan {
pNode = currNode.getParent();
simpul saat ini = simpul p;
} while (parentNodeId.equalsIgnoreCase(pNode.getName()));
kembalikan pNode;
}
/**
* Hasilkan file Word
*/
@SuppressWarnings("tidak dicentang")
pembuatan String publik(Templat templat) {
InputStream di = null;
OutputStream fo = null;
//Jalur ke file yang dihasilkan
String file = "d://test//" + templat.getDesc() + ".doc";
mencoba {
//Baca file templat
di = ini.getClass().getClassLoader()
.getResourceAsStream(template.getTemplateFile());
SAXBuilder sb = SAXBuilder baru();
Dokumen doc = sb.build(in);
Elemen root = doc.getRootElement(); // Dapatkan elemen root
Namespace ns = root.getNamespace();// NameSpace
// Elemen <wx:sect> ada di templat Word 03
Daftar<elemen> sekteList = root.getChild("body", ns).getChildren();
Elemen sekteElemen = (Elemen) sekteList.get(0);
// Kumpulan tag di bawah <w:p>
Daftar<elemen> pTagList = sectionElement.getChildren("p", ns);
// Kumpulan tag di bawah <w:tbl>
Daftar<elemen> tblTagList = sectionElement.getChildren("tbl", ns);
jika (pTagList != null && pTagList.size() > 0) {
changeValue4PTag(pTagList, template.getRules(), ns, null);
}
jika (tblTagList != null && tblTagList.size() > 0) {
changeValue4TblTag(tblTagList, template.getRules(), ns);
}
// menulis berkas
XMLOutputter keluaran = XMLOutputter baru(" ", benar, "UTF-8");
fo = FileOutputStream baru(file);
keluaran.output(doc, fo);
} tangkapan (FileNotFoundException e) {
e.printStackTrace();
} tangkapan (JDOMException e) {
e.printStackTrace();
} tangkapan (IOException e) {
e.printStackTrace();
} Akhirnya {
mencoba {
melampirkan();
fo.close();
} tangkapan (Pengecualian e) {
e.printStackTrace();
}
}
mengembalikan berkas;
}
/**
* Untuk templat WORD tingkat <w:body><wx:sect><w:p>, cari dan ganti tag di bawah <w:p>.
* @param pTagList:<w:p>koleksi
* @param RulesValue: Koleksi RuleDTO
* @param ns: Objek NameSpace
* @param trChildren: kumpulan node anak <w:tr> dari <w:tbl>
*/
@SuppressWarnings("tidak dicentang")
boolean pribadi changeValue4PTag(Daftar<elemen> pTagList,
Vektor<ruledto> ruleValue, Namespace ns, Daftar<element> trChildren) {
Elemen p = nol;
boolean delFlag = salah;
untuk (int i = 0; i < pTagList.size(); i++) {
boolean delCurrNode = false;//Hapus node saat ini
boolean delCurrNode4TabWR = false;//Menghapus satu simpul baris dalam tabel
p = (Elemen) pTagList.get(i);
Daftar<elemen> pChild = p.getChildren("r", ns);
for (int j = 0; pChild != null && j < pChild.size(); j++) {
Elemen pChildren = (Elemen) pChild.get(j);
Elemen t = pChildren.getChild("t", ns);
jika (t != nol) {
String teks = t.getTextTrim();
if (teks.indexOf("【※") != -1) {
for (int v = 0; v < ruleValue.ukuran(); v++) {
RuleDTO dto = (RuleDTO) ruleValue.get(v);
if (text.indexOf(dto.getParmDesc().trim()) != -1) {
// Tentukan apakah nilai atribut dapat dibatalkan untuk dihapus
if ("T".sama dengan(dto.getIfEmptyDelete())
&& StringUtils.isBlank(dto
.getParmValue())) {
//Hapus node teratas dari node ini
teks = "";
if (trChildren != null) {//Hapus baris ini untuk <w:tbl>
Elemen elemen = ((Elemen) hal
.getParent()).getParent();
trChildren.remove(elemen);
delCurrNode4TabWR = benar;
} else {//Hapus segmen untuk <w:r>
// pTagList.hapus(p);
pTagList.remove(pChildren);
delCurrNode = benar;
}
merusak;
} kalau tidak {
teks = teks.replaceAll(dto.getParmDesc()
.trim(), dto.getParmValue());
}
}
}
t.setText(teks);
}
if (delCurrNode4TabWR) {// <w:tbl>Node baris di bawah TABLE telah dihapus
delBendera = benar;
merusak;
} else if (delCurrNode) {// Node di bawah <w:p> telah dihapus
Saya--;
delBendera = benar;
merusak;
}
}
}
}
kembalikan delFlag;
}
/**
* Untuk templat WORD yang berisi tabel, cari dan ganti tag di bawah <w:tbl>.
* @param tblTagList:<w:tbl> koleksi
* @param ruleValue: Koleksi RuleDTO
* @param ns: Objek NameSpace
*/
@SuppressWarnings("tidak dicentang")
kekosongan pribadi changeValue4TblTag(Daftar<elemen> tblTagList,
Vektor<ruledto> ruleValue, Namespace ns) {
Elemen p = nol;
untuk (int i = 0; tblTagList != null && i < tblTagList.size(); i++) {
p = (Elemen) tblTagList.get(i);
Daftar<elemen> trChildren = p.getChildren("tr", ns);
for (int j = 0; trChildren != null && j < trChildren.size(); j++) {// Loop<w:tr>
Elemen pChildren = (Elemen) trChildren.get(j);
Daftar<elemen> tcTagList = pChildren.getChildren("tc", ns);
for (int c = 0; tcTagList != null && c < tcTagList.size(); c++) {// Ulangi <w:tc> untuk mendapatkan koleksi <w:p>
Elemen tcChildren = (Elemen) tcTagList.get(c);
Daftar<elemen> pTagList = tcChildren.getChildren("p", ns);
boolean delFlag = changeValue4PTag(pTagList, ruleValue,
ns, trAnak-anak);
if (delFlag) {// Setelah menghapus baris, Anda perlu mengubah posisi penunjuk trChildren
J--;
}
}
}
}
}
public static void main(String[] args) melempar Pengecualian {
Kata WordBuilder = WordBuilder baru();
Peta<string, string=""> peta = HashMap baru<string, string="">();
//isi parameter
map.put("ToPartment", "Perusahaan XXX");
map.put("Nama Pemilik", "Zhang San");
map.put("JumlahJumlah", "5");
map.put("Bisnis", "Pemeriksaan Rutin");
map.put("Hari Berguna", "15");
map.put("Tahun", "2014");
map.put("Bulan", "5");
map.put("Hari", "13");
map.put("ruleName", "RECOMMEND-LETTER");
Templat templat = word.loadRules(peta);
//Buka file secara langsung
Runtime.getRuntime().exec("explorer " + word.build(template));
}
}</string,></string,></element></w:p></w:tc></element></w:tr></element></ruledto></element>< /w:tbl></w:tbl></w:p></w:tbl></w:r></w:tbl></element></element></ruledto></ele ment></w:tr></w:tbl></w:p></w:p></w:p></wx:sect></w:body></element></ w:tbl></element></w:p></element></wx:sect></string,></ruledto></element></ruledto></element></string,>
Langkah 4: Selesai
Beberapa poin ringkasan dan catatan:
1. Nama elemen yang ditentukan harus konsisten dengan nilai yang sesuai dengan nama yang sama di template_rule.xml, jika tidak, aturan konversi perlu ditetapkan.
2. Teks di placeholder [※※] yang ditentukan dalam template xml harus sama dengan deskripsi terkait di template_rule.xml, jika tidak, aturan konversi perlu ditetapkan.
3. Setelah mengkonfigurasi template XML, Anda perlu memeriksa apakah node anak di bawah label adalah label (terkait dengan versi WORD).
4. Jika Anda ingin menghapus node label secara dinamis, konten node ini harus berada di baris yang sama di template. Jika tidak, Anda dapat menyesuaikan XML template secara manual.
5. Jika Anda perlu menerapkan fungsi pembungkusan baris otomatis WORD (belum ada solusi yang lebih baik untuk pembungkusan baris dalam templat), Anda harus terlebih dahulu menghitung jumlah kata di baris templat yang sesuai, lalu menggunakan pengisian spasi untuk mencapainya.