Microsoft Word (MS)- một trong các tiện ích từ bộ Microsoft Office là một trong những phần mềm phổ biến trong việc tạo ra file document, hỗ trợ đọc và ghi nội dung từ đơn giản đến phức tạp. Mặc dù con người có thể trực tiếp tạo và viết nội dung lên file MS, tuy nhiên trong rất nhiều tác vụ cần máy tính xử lý và tự động tạo nội dung trên các file MS. Ví dụ bạn đọc nội dung từ file pdf và muốn chuyển nội dung sang file docx hoặc bạn đang phát triển một mô hình xử lý ngôn ngữ tự nhiên và cần đọc dữ liệu đầu vào là các file MS thì Python-Docx là một trong những thư viện rất đáng để bạn lựa chọn.
Hôm nay mình xin giới thiệu các bạn cách tạo ra tự động file MS cũng như các tính năng thêm, sửa, xóa các nội dung dưới sự hỗ trợ của thư viện Python Docx.
1. Cài đặt thư viện
Nếu các bạn đang sử dụng anaconda, các bạn có thể dễ dàng cài đặt bằng cách sau đây:
1 2 | pip install python-docx |
2. Khởi tạo file
Để mở một file đã tồn tại trước đó, bạn sử dụng câu lệnh sau
1 2 3 4 | <span class="token keyword">from</span> docx <span class="token keyword">import</span> Document document <span class="token operator">=</span> Document<span class="token punctuation">(</span><span class="token string">'existing-document-file.docx'</span><span class="token punctuation">)</span> |
Nếu file này chưa tồn tại, bạn sử dụng câu lệnh sau:
1 2 | document <span class="token operator">=</span> Document<span class="token punctuation">(</span><span class="token punctuation">)</span> |
Sau khi bạn khởi tạo file, bạn có thể chỉnh sửa nội dung của file MS như thêm đoạn văn, thêm bảng, … thông qua biến document như ví dụ bên trên. Sau khi hoàn thiện bạn có lưu lại những thay đổi bằng câu lệnh sau :
1 2 | document.save(filename) |
Ở đây, filename là tên file mà bạn muốn lưu. Tất nhiên đuôi là .docx nhé.
3. Heading, title
Thư viện python-docx hỗ trợ ghi phần title hoặc heading của văn bản theo nhiều level mà người dùng chỉ định.
- Content: nội dung title hoặc heading
- Level: bậc của heading (0, 1, 2, …). Số càng nhỏ font chữ càng lớn.
1 2 | document<span class="token punctuation">.</span>add_heading<span class="token punctuation">(</span>content<span class="token punctuation">,</span> level<span class="token punctuation">)</span> |
3.1. Title
Theo mặc định của python-docx, title có level là 0
1 2 | document<span class="token punctuation">.</span>add_heading<span class="token punctuation">(</span>"This <span class="token keyword">is</span> a title part<span class="token punctuation">,</span> level<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">)</span> |
Ta có kết quả tương ứng sẽ là :
3.2. Heading
Đối với các phần heaing, ta có các level 1, 2, 3….
- Level 1
1 2 | document<span class="token punctuation">.</span>add_heading<span class="token punctuation">(</span><span class="token string">"This is a heading 1"</span><span class="token punctuation">,</span> level<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">)</span> |
Kết quả tương ứng :
- Level 2
1 2 | document<span class="token punctuation">.</span>add_heading<span class="token punctuation">(</span><span class="token string">"This is a heading 2"</span><span class="token punctuation">,</span> level<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">)</span> |
Kết quả tương ứng :
4. Đoạn văn (paragraph)
Trong các loại văn bản thông thường, chúng ta có hai cách biểu diễn nội dung của một trang đó là:
- Layout truyền thống: nội dung được biển diễn từ trên xuống dưới, từ trái sang phải
- Layout dạng cột : Nội dung được tổ chức thành từng cột riêng rẽ với nhau
4.1. Layout truyền thống
Với layout kiểu truyền thống, chúng ta ghi nội dung vào file MS như sau:
1 2 | document.add_paragraph(content) |
Kết quả tương ứng:
4.2. Layout dạng cột
Để tạo ra được các văn bản dạng cột. Chúng ta cần dùng đến khái niệm Section. Mỗi section có thể chứa nhiều các đoạn văn. Mỗi section sẽ tương đương với một page và chúng ta thông qua section để biểu diễn nội dung cho một page.
Tạo layout cột cho section :
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">from</span> docx<span class="token punctuation">.</span>enum<span class="token punctuation">.</span>section <span class="token keyword">import</span> WD_SECTION_START <span class="token keyword">def</span> <span class="token function">set_number_of_columns</span><span class="token punctuation">(</span>section<span class="token punctuation">,</span> cols<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" sets number of columns through xpath. """</span> WNS_COLS_NUM <span class="token operator">=</span> <span class="token string">"{http://schemas.openxmlformats.org/wordprocessingml/2006/main}num"</span> section<span class="token punctuation">.</span>_sectPr<span class="token punctuation">.</span>xpath<span class="token punctuation">(</span><span class="token string">"./w:cols"</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token builtin">set</span><span class="token punctuation">(</span>WNS_COLS_NUM<span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>cols<span class="token punctuation">)</span><span class="token punctuation">)</span> section <span class="token operator">=</span> document<span class="token punctuation">.</span>add_section<span class="token punctuation">(</span>WD_SECTION_START<span class="token punctuation">.</span>NEW_PAGE<span class="token punctuation">)</span> <span class="token comment"># col_nb is number of column layout</span> set_number_of_columns<span class="token punctuation">(</span>section<span class="token punctuation">,</span> col_nb<span class="token punctuation">)</span> |
Sau đó chúng ta thực hiện thêm đoạn văn giống như kiểu layout truyền thống. Đoạn văn sẽ được thêm theo thứ tự các cột, từ trái sang phải.
1 2 | p <span class="token operator">=</span> document<span class="token punctuation">.</span>add_paragraph<span class="token punctuation">(</span>content<span class="token punctuation">)</span> |
Ngoài ra, chúng ta cũng có thể thêm phần căn lề (trái, phải, giữa ) cho đoạn văn như sau:
1 2 | <span class="token keyword">from</span> docx<span class="token punctuation">.</span>enum<span class="token punctuation">.</span>text <span class="token keyword">import</span> WD_PARAGRAPH_ALIGNMENT |
- Căn lề trái
1 2 | p<span class="token punctuation">.</span>alignment <span class="token operator">=</span> WD_PARAGRAPH_ALIGNMENT<span class="token punctuation">.</span>LEFT |
- Căn lề phải
1 2 | p<span class="token punctuation">.</span>alignment <span class="token operator">=</span> WD_PARAGRAPH_ALIGNMENT<span class="token punctuation">.</span>RIGHT |
- Căn lề giữa
1 2 | p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER |
- Căn lề hai bên
1 2 | p.alignment = WD_PARAGRAPH_ALIGNMENT.JUSTIFY |
4.3. Thêm câu cho đoạn văn
Thư viện python-docx hỗ trợ chèn thêm câu riêng lẻ vào trong đoạn văn đã được khởi tạo:
1 2 3 4 5 6 | <span class="token comment"># initialize new paragraph</span> p <span class="token operator">=</span> document<span class="token punctuation">.</span>add_paragraph<span class="token punctuation">(</span>content<span class="token punctuation">)</span> <span class="token comment"># add sentence to initialized paragraph</span> sentence_element <span class="token operator">=</span> p<span class="token punctuation">.</span>add_run<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>content<span class="token punctuation">)</span><span class="token punctuation">)</span> |
4.3.1. Highlight background
Bạn cũng có thể highlight background cho từng câu bằng các màu yêu thích như sau:(highlight là tên màu )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <span class="token keyword">from</span> docx<span class="token punctuation">.</span>enum<span class="token punctuation">.</span>text <span class="token keyword">import</span> WD_COLOR_INDEX <span class="token keyword">if</span> highlight <span class="token operator">==</span> <span class="token string">'black'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>BLACK <span class="token keyword">elif</span> highlight <span class="token operator">==</span> <span class="token string">'blue'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>BLUE <span class="token keyword">elif</span> highlight <span class="token operator">==</span> <span class="token string">'green'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>BRIGHT_GREEN <span class="token keyword">elif</span> highlight <span class="token operator">==</span> <span class="token string">'dark blue'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>DARK_BLUE <span class="token keyword">elif</span> highlight <span class="token operator">==</span> <span class="token string">'dark red'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>DARK_RED <span class="token keyword">elif</span> highlight <span class="token operator">==</span> <span class="token string">'dark yellow'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>DARK_YELLOW <span class="token keyword">elif</span> highlight <span class="token operator">==</span> <span class="token string">'dark green'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>GREEN <span class="token keyword">elif</span> highlight <span class="token operator">==</span> <span class="token string">'pink'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>PINK <span class="token keyword">elif</span> highlight <span class="token operator">==</span> <span class="token string">'red'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>PINK <span class="token keyword">elif</span> highlight <span class="token operator">==</span> <span class="token string">'white'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>WHITE <span class="token keyword">elif</span> highlight <span class="token operator">==</span> <span class="token string">'teal'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>TEAL <span class="token keyword">elif</span> highlight <span class="token operator">==</span> <span class="token string">'yellow'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>YELLOW <span class="token keyword">elif</span> highlight <span class="token operator">==</span> <span class="token string">'violet'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>VIOLET <span class="token keyword">elif</span> highlight <span class="token operator">==</span> <span class="token string">'gray25'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>GRAY_25 <span class="token keyword">elif</span> highlight <span class="token operator">==</span> <span class="token string">'gray50'</span><span class="token punctuation">:</span> color_element <span class="token operator">=</span> WD_COLOR_INDEX<span class="token punctuation">.</span>GRAY_50 style <span class="token operator">=</span> document<span class="token punctuation">.</span>styles<span class="token punctuation">.</span>add_style<span class="token punctuation">(</span><span class="token string">"document style"</span><span class="token punctuation">,</span> WD_STYLE_TYPE<span class="token punctuation">.</span>CHARACTER<span class="token punctuation">)</span> style<span class="token punctuation">.</span>font<span class="token punctuation">.</span>highlight_color <span class="token operator">=</span> color_element sentence_element <span class="token operator">=</span> p<span class="token punctuation">.</span>add_run<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">,</span> style<span class="token operator">=</span>self<span class="token punctuation">.</span>style<span class="token punctuation">)</span> |
4.3.2. In đậm, nghiêng, gạch chân
Bạn cũng có thể thêm highlight cho bằng thêm in đậm, in nghiêng hay gạch chân như khi người sử dụng trực tiếp trên file MS.
1 2 3 4 5 6 | # set bold, italic, underline value which is boolean value True or False sentence_element = p.add_run(str(content) sentence_element.bold = bold sentence_element.italic = italic entence_element.underline = underline |
5. Picture
Bạn cũng có thể chèn ảnh trưc tiếp vào python-docx bằng đường dẫn tới file ảnh cần chèn hoặc ảnh đã được biểu diễn dạng ma trận. Bạn cũng có thể điều chỉnh kích thước ảnh phù hợp với văn bản của mình.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <span class="token keyword">import</span> cv2 <span class="token keyword">from</span> docx<span class="token punctuation">.</span>shared <span class="token keyword">import</span> Inches <span class="token keyword">from</span> io <span class="token keyword">import</span> BytesIO <span class="token keyword">import</span> numpy <span class="token keyword">as</span> np <span class="token keyword">def</span> <span class="token function">add_picture</span><span class="token punctuation">(</span>document<span class="token punctuation">,</span> image_path_or_stream<span class="token punctuation">,</span> width<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""Add picture to image"""</span> <span class="token keyword">if</span> <span class="token builtin">isinstance</span><span class="token punctuation">(</span>image_path_or_stream<span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">)</span><span class="token punctuation">:</span> img <span class="token operator">=</span> cv2<span class="token punctuation">.</span>imread<span class="token punctuation">(</span>image_path_or_stream<span class="token punctuation">)</span> <span class="token keyword">else</span><span class="token punctuation">:</span> img <span class="token operator">=</span> np<span class="token punctuation">.</span>array<span class="token punctuation">(</span>image_path_or_stream<span class="token punctuation">)</span> is_success<span class="token punctuation">,</span> im_buf_arr <span class="token operator">=</span> cv2<span class="token punctuation">.</span>imencode<span class="token punctuation">(</span><span class="token string">".jpg"</span><span class="token punctuation">,</span> img<span class="token punctuation">)</span> byte_im <span class="token operator">=</span> im_buf_arr<span class="token punctuation">.</span>tobytes<span class="token punctuation">(</span><span class="token punctuation">)</span> stream <span class="token operator">=</span> BytesIO<span class="token punctuation">(</span>byte_im<span class="token punctuation">)</span> document<span class="token punctuation">.</span>add_picture<span class="token punctuation">(</span>stream<span class="token punctuation">,</span> width<span class="token operator">=</span>Inches<span class="token punctuation">(</span>width<span class="token punctuation">)</span><span class="token punctuation">)</span> add_picture<span class="token punctuation">(</span>document<span class="token punctuation">,</span> <span class="token string">'example.jpg'</span><span class="token punctuation">,</span> <span class="token number">5.0</span><span class="token punctuation">)</span> |
Lời kết
Python-docx là một thư viện hỗ trợ mạnh mẽ về cách tạo lập hay sửa đổi văn bản docx. Tuy nhiên để có thể tận dụng hết các tính năng của Microsoft Word thì các bạn cần tìm hiểu sâu thêm các api của Mircosoft Word. Còn nếu bạn chỉ muốn sử dụng tính năng đơn giản thì python-docx vẫn là sự lựa chọn hết sức tuyệt vời. Cảm ơn các bạn đã theo dõi bài đọc của mình