Chúng tôi tạo tài liệu Microsoft Word bằng PHP. Exwog - trình tạo báo cáo từ Excel sang Word bằng mẫu Cho phép bạn đặt ký tự đóng khung cho tên cột Excel

MỘT, họ trong cột B và ngành nghề ở cột C.

2. Tạo tài liệu word (.doc hoặc .docx)


(MỘT), (B)(C).

(MỘT), (B)(C) (MỘT)- tên, (B)- họ, (C)- nghề nghiệp.

Cài đặt các chương trình.

3. Chọn đường dẫn cho file và thư mục


Lựa chọn

4. Chỉ định các sheet và dòng dữ liệu cần thiết


Bảng dữ liệu file Excel

Hàng dữ liệu tệp Excel Bảng dữ liệu file Excel

1 .

Nếu bạn muốn tất cả các trang và/hoặc hàng trong tệp Excel có dữ liệu tham gia vào quá trình hình thành tài liệu, hãy nhấp vào nút tương ứng ở bên phải có dòng chữ số(dòng chữ của nó sẽ thay đổi thành Tất cả).

5. Đặt mẫu đặt tên file word mới


Đặt mẫu đặt tên cho file word mới:

Mẫu tên file word mới- đây là mẫu tên của tài liệu mới (file word) do chương trình tạo ra. Ở đây mẫu tên chứa tên cột của tệp excel, được bao quanh bởi dấu ngoặc nhọn: (MỘT)(B). Khi tạo một tài liệu mới, chương trình sẽ thay thế mọi thứ (MỘT)(B) các giá trị ô tương ứng từ tệp excel - đây sẽ là tên của tài liệu mới (tệp word).

Bạn có thể đặt các ký tự đóng khung của mình trên tab Cài đặt các chương trình.

6. Nhấp vào "Tạo"


Nhấn vào nút Phát ra và tiến trình sẽ xuất hiện trên màn hình. Chính xác thì số lượng tài liệu (file word) sẽ được tạo ra bằng số dòng trong file excel tham gia vào việc hình thành.

7. Mọi thứ


Tất cả tài liệu (file word) đã được tạo và nằm trong thư mục được chỉ định trong Thư mục lưu file word mới. Tất cả:)

Exwog- trình tạo báo cáo từ Excel sang Word bằng mẫu

Trình tạo tệp Word miễn phí sử dụng mẫu (tệp Word) dựa trên dữ liệu tệp Excel

Hoạt động trên Mac OS, Windows và Linux

Cho phép bạn đặt tên cho file word mới được tạo

Cho phép bạn chỉ định các trang và hàng dữ liệu cần thiết

Cho phép bạn chỉ định các ký tự xung quanh cho tên cột Excel

Dễ dàng sử dụng

Lưu trữ dữ liệu của bạn ở định dạng Excel (.xls và .xlsx) và tạo tệp Word (.doc và .docx) chỉ sau vài cú nhấp chuột :)


Làm thế nào nó hoạt động?

Hãy xem tập tin excel của bạn


Trong ví dụ này, tệp excel chứa thông tin về khách hàng. Mỗi dòng tương ứng với một khách hàng cụ thể. Tên được sắp xếp theo cột MỘT, họ trong cột B và ngành nghề ở cột C.

Bấm vào để xem

Tạo tài liệu word (.doc hoặc .docx)


Bấm vào để xem

Tạo một “mẫu” (tệp word) để tạo tài liệu mới (tệp word). Ở đây văn bản "mẫu" chứa tên các cột của tệp excel, được bao quanh bởi dấu ngoặc nhọn: (MỘT), (B)(C).

Chương trình sẽ sinh ra các văn bản mới theo “mẫu” thay thế toàn bộ (MỘT), (B)(C) giá trị ô tương ứng từ file excel: (MỘT)- tên, (B)- họ, (C)- nghề nghiệp.

Bạn cũng có thể đặt các ký tự đóng khung của mình trên tab Cài đặt các chương trình.

Chọn đường dẫn cho file và thư mục


Chọn đường dẫn cho các tập tin và thư mục (các nút có nhãn Lựa chọn). Trong chương trình, bạn chỉ định các đường dẫn sau:

Tệp Excel có dữ liệu (*.xls, *.xlsx)- đây là đường dẫn tới file Excel kèm theo dữ liệu (thông tin khách hàng);

Tệp mẫu Word (*.doc, *.docx)- đây là đường dẫn đến “mẫu” của bạn (tệp word được tạo ở bước trước);

Thư mục lưu file word mới- đây là đường dẫn đến thư mục mà chương trình sẽ lưu các tài liệu mới được tạo.

Bấm vào để xem

Chỉ định các trang tính và hàng của dữ liệu cần thiết


Bấm vào để xem

Chỉ định số lượng trang và hàng trong tệp excel của bạn với dữ liệu (thông tin khách hàng) mà bạn muốn tạo tài liệu:

Bảng dữ liệu file Excel- số trang trong tệp excel của bạn sẽ tham gia vào việc hình thành các tài liệu mới;

Hàng dữ liệu tệp Excel- số dòng của tờ (trang được chỉ định trong Bảng dữ liệu file Excel) của tệp excel của bạn, tệp này sẽ tham gia vào quá trình tạo tài liệu mới. Dựa trên dữ liệu của từng dòng được chỉ định, một tài liệu riêng biệt (file word) sẽ được tạo.

Việc đánh số trang và dòng trong chương trình bắt đầu bằng 1 .

Chúng ta đang sống trong một thế giới nơi các nhà phát triển PHP thỉnh thoảng phải tương tác với hệ điều hành Windows. WMI (Giao diện quản lý Windows) là một ví dụ như vậy - tương tác với Microsoft Office.

Trong bài viết này, chúng ta sẽ xem xét cách tích hợp đơn giản giữa Word và PHP: tạo tài liệu Microsoft Word dựa trên các trường đầu vào ở dạng HTML bằng cách sử dụng PHP (và tiện ích mở rộng Interop của nó).

Các bước chuẩn bị

Trước hết, hãy đảm bảo rằng chúng ta đã cấu hình môi trường WAMP cơ bản. Vì Interop chỉ có trên Windows nên chúng tôi cần triển khai máy chủ Apache và cài đặt PHP trên máy Windows. Ở khả năng này, tôi sử dụng EasyPHP 14.1, cực kỳ dễ cài đặt và cấu hình.

Việc tiếp theo bạn cần làm là cài đặt Microsoft Office. Phiên bản không quan trọng lắm. Tôi đang sử dụng Microsoft Office 2013 Pro nhưng mọi phiên bản Office cũ hơn 2007 đều ổn.

Chúng tôi cũng cần đảm bảo rằng chúng tôi đã cài đặt các thư viện để phát triển ứng dụng Interop (PIA, Tập hợp Interop chính, Tập hợp Interop chính). Bạn có thể tìm hiểu bằng cách mở Windows Explorer và vào thư mục \assembly và ở đó chúng ta sẽ thấy một tập hợp các tập hợp đã được cài đặt:

Tại đây bạn có thể thấy phần tử Microsoft.Office.Interop.Word (được gạch chân trong ảnh chụp màn hình). Đây sẽ là bản dựng mà chúng tôi sẽ sử dụng trong bản demo của mình. Vui lòng đặc biệt chú ý đến các trường “Tên tập hợp”, “Phiên bản” và “Mã thông báo khóa công khai”. Chúng tôi sẽ sớm sử dụng chúng trong tập lệnh PHP của mình.

Thư mục này cũng chứa các tập hợp khác (bao gồm toàn bộ dòng Office) có sẵn để sử dụng trong các chương trình của bạn (không chỉ cho PHP mà còn cho VB.net, C#, v.v.).

Nếu danh sách các tập hợp không bao gồm toàn bộ gói Microsoft.Office.Interop thì chúng ta cần cài đặt lại Office bằng cách thêm PIA hoặc tải xuống gói theo cách thủ công từ trang web của Microsoft và cài đặt nó. Để biết hướng dẫn chi tiết hơn, vui lòng tham khảo trang MSDN này.

Bình luận: Chỉ có bản phân phối PIA Microsoft Office 2010 mới có sẵn để tải xuống và cài đặt Phiên bản của các tập hợp trong gói này là 14.0.0 và phiên bản 15 chỉ được cung cấp với Office 2013.

Cuối cùng, bạn cần kích hoạt tiện ích mở rộng php_com_dotnet.dll trong php.ini và khởi động lại máy chủ.

Bây giờ bạn có thể chuyển sang lập trình.

biểu mẫu HTML

Vì phần lớn ví dụ này là ở phía máy chủ, nên chúng tôi sẽ tạo một trang đơn giản với biểu mẫu trông như thế này:

Chúng tôi có trường văn bản cho tên, một nhóm nút radio cho giới tính, thanh trượt cho độ tuổi và khu vực nhập văn bản để nhập tin nhắn cũng như nút “Gửi” khét tiếng.

Lưu tệp này dưới dạng “index.html” trong thư mục máy chủ ảo để có thể truy cập tệp này tại địa chỉ như http://test/test/interop.

Phần máy chủ

Tệp xử lý phía máy chủ là mục tiêu chính của cuộc trò chuyện của chúng tôi. Để bắt đầu, tôi sẽ cung cấp mã hoàn chỉnh cho tệp này và sau đó tôi sẽ giải thích từng bước.

nhìn thấy được = đúng; $fn = __DIR__ . "\\template.docx"; $d = $w->Documents->Open($fn); echo "Tài liệu đang mở.


"; $flds = $d->Fields; $count = $flds->Count; echo "Có các trường $count trong tài liệu.
"; tiếng vang"
    "; $mapping = setupfields(); foreach ($flds as $index => $f) ( $f->Select(); $key = $mapping[$index]; $value = $inputs[$key]; if ($key == "giới tính") ( if ($value == "m") $value = "Ông."; else $value = "Bệnh đa xơ cứng."; } if($key=="printdate") $value= date ("Y-m-d H:i:s"); $w->Selection->TypeText($value); echo "!}
  • Tôi gán trường $index: $key giá trị $value
  • "; ) vang vọng"
"; echo "Xử lý hoàn tất!

"; echo "Tôi đang gõ, vui lòng đợi...
"; $d->PrintOut(); sleep(3); echo "Xong!"; $w->Quit(false); $w=null; function setupfields() ( $mapping = array(); $mapping = "giới tính"; $mapping = "tên"; $mapping = "tin nhắn"; $mapping = "printdate";

Sau khi điền vào biến $inputs các giá trị nhận được từ biểu mẫu, đồng thời tạo một phần tử trống bằng khóa printdate (chúng ta sẽ thảo luận lý do tại sao chúng ta làm điều này sau), chúng ta đi đến bốn dòng rất quan trọng:

$assembly = "Microsoft.Office.Interop.Word, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"; $class = "Microsoft.Office.Interop.Word.ApplicationClass"; $w = DOTNET mới($assembly, $class); $w->visible = true;

Trình thao tác COM trong PHP yêu cầu tạo một thể hiện của lớp trong một “hội”. Trong trường hợp của chúng tôi, chúng tôi làm việc với Word. Nếu nhìn vào ảnh chụp màn hình đầu tiên, bạn có thể viết chữ ký lắp ráp đầy đủ cho Word:

  • “Tên”, “Phiên bản”, “Mã thông báo khóa công khai” - tất cả điều này được lấy từ thông tin có thể xem được trong “c:\Windows\assembly“.
  • “Văn hóa” luôn trung lập

Lớp mà chúng ta muốn tham chiếu luôn được gọi là “tên hợp ngữ” + “ .ApplicationClass “.

Bằng cách thiết lập hai tham số này, chúng ta có thể có được một đối tượng để làm việc với Word.

Đối tượng này có thể vẫn ở chế độ nền hoặc chúng ta có thể đặt nó vào chế độ làm việc bằng cách đặt thuộc tính hiển thị thành true.

Bước tiếp theo là mở tài liệu cần xử lý và ghi một phiên bản của “tài liệu” vào biến $d.

Để tạo nội dung trong tài liệu dựa trên dữ liệu biểu mẫu, bạn có thể thực hiện một số cách.

Điều tồi tệ nhất là mã hóa nội dung của tài liệu bằng PHP và sau đó xuất nó thành tài liệu Word. Tôi thực sự khuyên bạn không nên làm điều này vì những lý do sau:

  1. Bạn mất đi tính linh hoạt. Mọi thay đổi đối với tệp đầu ra sẽ yêu cầu thay đổi mã PHP.
  2. Điều này phá vỡ sự tách biệt giữa kiểm soát và xem
  3. Việc áp dụng kiểu cho nội dung tài liệu (căn chỉnh, phông chữ, kiểu, v.v.) trong tập lệnh sẽ làm tăng đáng kể số lượng dòng mã. Thay đổi phong cách theo chương trình là quá cồng kềnh.

Một lựa chọn khác là sử dụng tìm kiếm và thay thế. PHP có các tiện ích tích hợp tốt cho việc này. Chúng ta có thể tạo một tài liệu Word trong đó chúng ta sẽ đặt các nhãn có dấu phân cách đặc biệt, sau này sẽ được thay thế. Ví dụ: chúng ta có thể tạo một tài liệu chứa đoạn mã sau:

và với sự trợ giúp của PHP, chúng ta có thể dễ dàng thay thế nó bằng nội dung của trường “Tên” nhận được từ biểu mẫu.

Nó đơn giản và cứu chúng ta khỏi mọi hậu quả khó chịu mà chúng ta gặp phải ở phương pháp đầu tiên. Chúng ta chỉ cần quyết định dấu phân cách chính xác, trong trường hợp đó chúng ta sẽ sử dụng một mẫu.

Tôi khuyên dùng phương pháp thứ ba và nó dựa vào kiến ​​thức sâu hơn về Word. Chúng tôi sẽ sử dụng các trường làm phần giữ chỗ và sử dụng mã PHP, chúng tôi sẽ cập nhật trực tiếp các giá trị trong các trường với các giá trị tương ứng.

Cách tiếp cận này linh hoạt, nhanh chóng và phù hợp với các phương pháp hay nhất của Word. Nó cũng có thể giúp bạn tránh tìm kiếm toàn văn bản trong tài liệu, điều này tốt cho hiệu suất. Tôi lưu ý rằng giải pháp này cũng có nhược điểm.

Word đã không hỗ trợ các chỉ mục được đặt tên cho các trường ngay từ đầu. Ngay cả khi chúng ta đã chỉ định tên cho các trường đang được tạo, chúng ta vẫn cần sử dụng mã định danh bằng số của các trường này. Điều này cũng giải thích tại sao chúng ta cần sử dụng một hàm (trường thiết lập) riêng biệt để khớp chỉ mục trường với tên trường từ biểu mẫu.

Trong bài học demo này, chúng ta sẽ sử dụng một tài liệu có 5 trường MERGEFIELD. Chúng tôi sẽ đặt tài liệu mẫu vào cùng vị trí với trình xử lý tập lệnh của chúng tôi.

Xin lưu ý rằng trường printdate không có trường tương ứng trên biểu mẫu. Đó là lý do tại sao chúng tôi đã thêm phần tử printdate trống vào mảng $inputs. Nếu không có điều này, tập lệnh vẫn sẽ khởi động và chạy, nhưng PHP sẽ đưa ra cảnh báo rằng chỉ mục printdate không nằm trong mảng $inputs.

Sau khi thay thế các trường bằng giá trị mới, chúng ta sẽ in tài liệu bằng cách sử dụng

$d->PrintOut();

Phương thức PrintOut có một số tham số tùy chọn và chúng tôi đang sử dụng dạng đơn giản nhất của nó. Thao tác này sẽ in một bản sao của tài liệu trên máy in mặc định được gắn vào máy Windows.

Bạn cũng có thể gọi PrintPreview để xem trước kết quả đầu ra trước khi in. Trong môi trường hoàn toàn tự động, tất nhiên chúng ta sẽ sử dụng phương pháp PrintOut.

Bạn có thể phải đợi một lúc trước khi tắt ứng dụng Word, do đó sẽ mất thời gian để xếp hàng lệnh in. Không có độ trễ(3), phương thức $w->Quit sẽ thực thi ngay lập tức và công việc không được xếp hàng đợi.

Cuối cùng, chúng ta gọi $w->Quit(false) , thao tác này sẽ đóng ứng dụng Word được tập lệnh của chúng ta gọi. Tham số duy nhất được truyền cho phương thức là lệnh lưu tệp trước khi thoát. Chúng tôi đã thực hiện các thay đổi đối với tài liệu nhưng chúng tôi không muốn lưu chúng vì chúng tôi cần một mẫu rõ ràng cho công việc sau này.

Sau khi hoàn tất mã, chúng ta có thể tải trang biểu mẫu của mình, điền vào một số giá trị và gửi nó. Các hình ảnh bên dưới hiển thị đầu ra của tập lệnh cũng như tài liệu Word được cập nhật:

Cải thiện tốc độ xử lý và biết thêm một chút về PIA

PHP là một ngôn ngữ được gõ yếu. Đối tượng COM thuộc loại Object. Trong khi viết tập lệnh, chúng ta không có cách nào để có được mô tả về một đối tượng, có thể là ứng dụng Word, tài liệu hoặc trường. Chúng tôi không biết đối tượng này có những thuộc tính gì hoặc nó hỗ trợ những phương thức nào.

Điều này sẽ làm chậm đáng kể tốc độ phát triển. Để tăng tốc độ phát triển, tôi khuyên bạn nên viết hàm trước bằng C#, sau đó dịch mã sang PHP. Tôi có thể giới thiệu một IDE miễn phí để phát triển C# có tên là “#develop”. Bạn có thể tìm nó. Tôi thích nó hơn Visual Studio vì #develop nhỏ hơn, đơn giản hơn và nhanh hơn.

Di chuyển mã C# sang PHP không đáng sợ như bạn tưởng. Hãy để tôi chỉ cho bạn một vài dòng trong C#:

Word.Application w=Word.Application() mới; w.Visible=true; Đường dẫn chuỗi=Application.StartupPath+"\\template.docx"; Word.Document d=w.Documents.Open(path) dưới dạng Word.Document; Word.Fields flds=d.Fields; int len=flds.Count; foreach (Word.Field f trong flds) ( f.Select(); int i=f.Index; w.Selection.TypeText("..."); )

Bạn sẽ nhận thấy rằng mã C# rất giống với mã PHP mà tôi đã trình bày trước đó. C# là một ngôn ngữ được định kiểu mạnh, vì vậy trong ví dụ này bạn sẽ nhận thấy rằng có một số toán tử ép kiểu và các biến đó cần phải được gõ.

Bằng cách chỉ định loại biến, bạn có thể tận hưởng mã sạch hơn và tự động hoàn thành, đồng thời tốc độ phát triển tăng lên đáng kể.

Một cách khác để tăng tốc độ phát triển PHP là gọi macro trong Word. Chúng tôi thực hiện cùng một chuỗi hành động và sau đó lưu nó dưới dạng macro. Macro được viết bằng Visual Basic, cũng dễ dàng dịch sang PHP.

Và quan trọng nhất, tài liệu Office PIA của Microsoft, đặc biệt là tài liệu về vùng tên cho từng ứng dụng Office, là tài liệu tham khảo chi tiết nhất hiện có. Ba ứng dụng được sử dụng nhiều nhất là:

  • Excel 2013: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel(v=office.15).aspx
  • Word 2013: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word(v=office.15).aspx
  • PowerPoint 2013: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint(v=office.15).aspx

Phần kết luận

Trong bài viết này, chúng tôi đã trình bày cách điền dữ liệu vào tài liệu Word bằng thư viện PHP COM và khả năng tương tác của Microsoft Office.

Windows và Office được sử dụng rộng rãi trong cuộc sống hàng ngày. Biết được sức mạnh của Office/Window và PHP sẽ hữu ích cho mọi nhà phát triển PHP và Windows.

Phần mở rộng PHP COM mở ra cơ hội sử dụng sự kết hợp này.

Trong các bài viết trước trong loạt bài “Tự động điền tài liệu”, tôi đã nói về cách tạo giao diện người dùng của ứng dụng, tổ chức xác thực dữ liệu đầu vào và lấy số bằng chữ mà không cần sử dụng mã VBA. Trong bài viết cuối cùng này, chúng ta sẽ nói về sự kỳ diệu của việc chuyển tất cả các giá trị cần thiết từ sổ làm việc Excel sang tài liệu Word. Hãy để tôi chỉ cho bạn điều gì sẽ xảy ra cuối cùng:

Mô tả cơ chế

Để bắt đầu, tôi sẽ mô tả một cách khái quát chính xác cách dữ liệu sẽ được chuyển sang tài liệu Word. Trước hết, chúng ta sẽ cần một mẫu tài liệu Word chứa tất cả các đánh dấu, bảng và phần văn bản sẽ không thay đổi. Trong mẫu này, bạn cần xác định vị trí mà các giá trị từ sổ làm việc Excel sẽ được thay thế; việc này được thực hiện thuận tiện nhất bằng cách sử dụng dấu trang. Sau này, bạn cần sắp xếp dữ liệu Excel theo cách đảm bảo tuân thủ mẫu Word và cuối cùng nhưng không kém phần quan trọng, hãy viết chính quy trình chuyển trong VBA.

Vì vậy, điều đầu tiên trước tiên.

Tạo mẫu tài liệu Word

Mọi thứ ở đây cực kỳ đơn giản - chúng tôi tạo một tài liệu thông thường, nhập và định dạng văn bản, nói chung, chúng tôi đạt được biểu mẫu yêu cầu. Ở những nơi bạn cần thay thế giá trị từ Excel, bạn cần tạo dấu trang. Điều này được thực hiện như sau:

Vì vậy, bạn sẽ cần phải tạo tất cả dấu trang, nghĩa là đánh dấu tất cả các vị trí sẽ chèn dữ liệu từ Excel. Tệp kết quả phải được lưu dưới dạng “Mẫu MS Word” bằng cách sử dụng mục menu “Tệp” -> “Lưu dưới dạng…”.

Chuẩn bị dữ liệu Excel

Để thuận tiện, tôi quyết định đặt tất cả dữ liệu cần chuyển sang tài liệu Word trên một bảng tính riêng có tên Bookmarks - dấu trang. Trang tính này có hai cột: cột đầu tiên chứa tên của các dấu trang (chính xác như chúng được đặt tên trong tài liệu Word) và cột thứ hai chứa các giá trị tương ứng sẽ được chuyển.

Một số giá trị này được lấy trực tiếp từ bảng nhập dữ liệu và một số được lấy từ các bảng phụ nằm trên bảng Hỗ trợ. Trong bài viết này, tôi sẽ không phân tích các công thức tính các giá trị cần thiết; nếu có điều gì chưa rõ, hãy đặt câu hỏi trong phần bình luận.

Ở giai đoạn này, điều quan trọng là phải chỉ định chính xác tất cả các tên dấu trang - tính chính xác của việc truyền dữ liệu phụ thuộc vào điều này.

Thủ tục chuyển nhượng

Nhưng đây là điều thú vị nhất. Có hai tùy chọn để thực thi mã di chuyển dữ liệu:

  • Mã chạy trong sổ làm việc Excel, dữ liệu được chuyển sang Word từng giá trị một và được đặt ngay vào tài liệu.
  • Mã được thực thi trong một tài liệu Word riêng biệt, tất cả dữ liệu được chuyển từ Excel trong một đợt.

Từ quan điểm về tốc độ thực thi, đặc biệt là với số lượng dấu trang lớn, tùy chọn thứ hai trông hấp dẫn hơn nhiều nhưng yêu cầu các hành động phức tạp hơn. Đó chính xác là những gì tôi đã sử dụng.

Đây là những gì bạn cần làm:

  • Tạo mẫu tài liệu Word có hỗ trợ macro. Mẫu này sẽ chứa mã VBA có thể thực thi được.
  • Trong mẫu đã tạo, bạn cần đặt một chương trình viết bằng VBA.Để thực hiện việc này, khi chỉnh sửa mẫu, hãy nhấn tổ hợp phím Alt+F11 và nhập mã chương trình vào cửa sổ soạn thảo Visual Basic mở ra.
  • Trong sổ làm việc Excel, viết mã gọi quy trình điền từ mẫu Word mới tạo.

Tôi sẽ không cung cấp nội dung của quy trình trong bài viết - bạn có thể dễ dàng xem nó trong tệp FillDocument.dotm, nằm trong thư mục Mẫu trong kho lưu trữ cùng với ví dụ.

Làm thế nào bạn có thể sử dụng tất cả điều này để giải quyết vấn đề cụ thể của bạn?

Tôi hiểu rằng về mặt ngôn từ thì tất cả những điều này trông rất đơn giản, nhưng điều gì xảy ra trong thực tế? Tôi đề nghị bạn chỉ cần sử dụng một tùy chọn làm sẵn. Tải xuống kho lưu trữ với ví dụ, trong sổ làm việc Excel, nhấn tổ hợp phím Alt+F11 để mở trình soạn thảo Visual Basic và đọc tất cả nhận xét của tôi về chương trình. Để thay đổi chương trình cho phù hợp với nhu cầu của bạn, bạn chỉ cần thay đổi giá trị của một số hằng số; chúng nằm ở đầu chương trình. Bạn có thể thoải mái sao chép toàn bộ văn bản của chương trình vào dự án của mình.

Cấu trúc lưu trữ

Kho lưu trữ kèm theo bài viết này chứa một số tập tin.

Tệp chính là sổ làm việc Excel có tên "Tạo xác nhận". Sổ làm việc này có 4 trang tính, trong đó chỉ có hai trang được hiển thị: “Đầu vào” - một trang nhập dữ liệu và “Cơ sở dữ liệu” - kho lưu trữ tất cả các tài liệu đã nhập.

Thư mục Mẫu chứa các mẫu tài liệu Word. Một trong số đó là mẫu chứa chương trình điền dấu trang và mẫu thứ hai là biểu mẫu để điền vào. Bạn có thể sử dụng mẫu mà không cần sửa đổi chương trình, nhưng biểu mẫu cần điền, tất nhiên, sẽ phải được làm lại cho phù hợp với nhu cầu của bạn.

Làm thế nào để làm lại ví dụ “cho chính bạn”?

  1. Chuẩn bị mẫu tài liệu Word để điền. Tạo tất cả các dấu trang cần thiết trong đó và lưu nó dưới dạng “mẫu MS Word”.
  2. Sao chép tệp FillDocument.dotm từ kho lưu trữ đính kèm bài viết này vào thư mục chứa mẫu đã chuẩn bị sẵn. Tệp này chịu trách nhiệm điền vào các dấu trang mẫu và không cần thay đổi gì trong đó.
  3. Chuẩn bị sổ làm việc Excel để nhập dữ liệu. Bạn có quyền quyết định xem nó có bất kỳ giao diện người dùng "nâng cao" nào và thực hiện các phép tính phức tạp khác nhau hay không. Điều chính là nó chứa một bảng tính với bảng tương ứng giữa tên của dấu trang trong mẫu Word và giá trị cần thay thế.
  4. Chèn mã chương trình VBA từ tệp ví dụ vào sổ làm việc đã chuẩn bị. Thay thế tất cả các hằng số theo dự án của bạn.
  5. Kiểm tra hoạt động chính xác.
  6. Hãy chủ động sử dụng nó!

Chúng ta tiếp tục chủ đề làm việc với các biểu mẫu trong Word mà chúng ta đã bắt đầu trước đó. Trong các bài viết trước, chúng tôi chỉ xem xét các biểu mẫu từ quan điểm của “người dùng nâng cao”, tức là. Chúng tôi đã tạo các tài liệu dễ dàng điền thủ công. Hôm nay tôi muốn đề xuất mở rộng nhiệm vụ này và cố gắng sử dụng cơ chế Kiểm soát nội dung để tạo tài liệu.

Trước khi chúng ta bắt tay vào nhiệm vụ trước mắt của mình, tôi muốn nói vài lời về cách lưu trữ dữ liệu để kiểm soát nội dung trong tài liệu Word (hiện tại tôi sẽ cố tình bỏ qua cách chúng liên kết với nội dung của tài liệu, nhưng tôi hy vọng sẽ quay lại về điều này đôi khi trong các bài viết tiếp theo).

Một câu hỏi hợp lý - nó là gì? itemProps1.xml và các thành phần tương tự? Các thành phần này lưu trữ mô tả về nguồn dữ liệu. Rất có thể, theo kế hoạch của các nhà phát triển, ngoài các tệp xml được tích hợp trong tài liệu, những tệp khác lẽ ra sẽ được sử dụng, nhưng cho đến nay chỉ có phương pháp này mới được triển khai.

Tại sao chúng hữu ích cho chúng ta? itemPropsX.xml? Thực tế là họ liệt kê các lược đồ xml (của họ không gian tên mục tiêu), được sử dụng trong cha mẹ itemX.xml. Điều này có nghĩa là nếu chúng ta đã đưa nhiều hơn một xml tùy chỉnh vào tài liệu thì để tìm được cái chúng ta cần, chúng ta cần phải thực hiện itemPropsX.xml các thành phần và tìm đúng mạch, và do đó đúng itemX.xml.

Bây giờ còn một điều nữa. Chúng tôi sẽ không phân tích thủ công các kết nối giữa các thành phần và tìm kiếm những kết nối chúng tôi cần mà chỉ sử dụng API Đóng gói cơ bản! Thay vào đó, chúng tôi sẽ sử dụng Open XML SDK (các bản dựng của nó có sẵn thông qua NuGet). Tất nhiên, chúng tôi chưa từng nói một lời nào về API này trước đây, nhưng đối với nhiệm vụ của chúng tôi, mức tối thiểu được yêu cầu đối với API này và tất cả mã sẽ khá minh bạch.

Vâng, phần giới thiệu cơ bản đã xong, chúng ta có thể bắt đầu với ví dụ.

Theo truyền thống đã được thiết lập, chúng ta sẽ lấy “Báo cáo cuộc họp” giống như chúng ta đã vẽ trong bài viết. Hãy để tôi nhắc bạn rằng mẫu tài liệu trông như thế này:

Và đây là XML mà các trường tài liệu được liên kết

< meetingNotes xmlns ="urn:MeetingNotes" subject ="" date ="" secretary ="" > < participants > < participant name ="" /> < decisions > < decision problem ="" solution ="" responsible ="" controlDate ="" />

Bước 1: Tạo mô hình dữ liệu

Trên thực tế, nhiệm vụ của chúng tôi không chỉ là tạo tài liệu mà còn tạo ra (ít nhất là ở phiên bản nháp) một công cụ thuận tiện để cả nhà phát triển và người dùng sử dụng.

Vì vậy, chúng ta sẽ khai báo model dưới dạng cấu trúc lớp C#:

Lớp công khai MeetNotes ( public MeetNotes() ( Người tham gia = Danh sách mới (); Quyết định = Danh sách mới (); ) chuỗi công khai Chủ đề ( get; set; ) public DateTime Ngày ( get; set; ) chuỗi công khai Thư ký ( get; set; ) public List Người tham gia ( get; set; ) Danh sách công khai Quyết định ( get; set; ) ) public class Quyết định ( public string Vấn đề ( get; set; ) public string Giải pháp ( get; set; ) public string Chịu trách nhiệm ( get; set; ) public DateTime ControlDate ( get; set; ) ) public Người tham gia lớp ( Tên chuỗi công khai ( get; set; ) )

Nhìn chung, không có gì đặc biệt, ngoại trừ các thuộc tính đã được thêm vào để kiểm soát việc tuần tự hóa XML (vì tên trong mô hình và XML được yêu cầu hơi khác nhau).

Bước 2: Tuần tự hóa mô hình trên thành XML

Về nguyên tắc, nhiệm vụ này là tầm thường. Cái được gọi là "lấy XmlSerializer yêu thích của chúng tôi và đi", nếu không phải vì một điều Nhưng

Thật không may, có vẻ như có một lỗi trong phiên bản Office hiện tại như sau: nếu trong xml tùy chỉnh trước bằng cách khai báo không gian tên chính (không gian mà Word sẽ lấy các phần tử để hiển thị), khai báo một số phần tử khác, sau đó lặp lại Các điều khiển nội dung bắt đầu được hiển thị không chính xác (chỉ khi nhiều phần tử được hiển thị như trong chính mẫu - tức là phần lặp lại không hoạt động ).

Những thứ kia. Đây là xml hoạt động:

< test xmlns ="urn:Test" attr1 ="1" attr2 ="2" > < repeatedTag attr ="1" /> < repeatedTag attr ="2" /> < repeatedTag attr ="3" />

Va cai nay cung vay:

< test xmlns ="urn:Test" attr1 ="1" attr2 ="2" xmlns:t ="urn:TTT" > < repeatedTag attr ="1" /> < repeatedTag attr ="2" /> < repeatedTag attr ="3" />

nhưng cái này không còn ở đó nữa:

< test xmlns:t ="urn:TTT" xmlns ="urn:Test" attr1 ="1" attr2 ="2" > < repeatedTag attr ="1" /> < repeatedTag attr ="2" /> < repeatedTag attr ="3" />

Tôi đã cố gửi lỗi tới bộ phận hỗ trợ của Microsoft trên Connect nhưng vì lý do nào đó tôi không có quyền gửi lỗi Office. Và cuộc thảo luận trên diễn đàn MSDN cũng không giúp được gì.

Nói chung, một cách giải quyết cần thiết. Nếu chúng tôi tạo XML bằng tay thì sẽ không có vấn đề gì - chúng tôi đã tự mình làm mọi thứ. Tuy nhiên, trong trường hợp này, tôi thực sự muốn sử dụng XmlSerializer tiêu chuẩn, theo mặc định, XmlSerializer sẽ thêm một số vùng tên của nó vào XML đầu ra, ngay cả khi những vùng tên này không được sử dụng.

Chúng tôi sẽ ngăn chặn hoàn toàn đầu ra của các không gian tên của chính chúng tôi trong XmlSerializer. Đúng, cách tiếp cận này sẽ chỉ hiệu quả nếu nó thực sự không cần đến chúng (nếu không chúng sẽ vẫn được thêm vào và ngay TRƯỚC chúng ta).

Trên thực tế, toàn bộ mã (với điều kiện là biến ghi chú cuộc họp chứa một đối tượng được điền trước đó thuộc loại MeetNotes):

var serializer = new XmlSerializer(typeof (MeetingNotes));
var serializedDataStream = new MemoryStream();

var namespaces = new XmlSerializerNamespaces();
namespaces.Add(“”, , “” );

serializer.Serialize(serializedDataStream, MeetNotes, không gian tên);
serializedDataStream.Seek(0, SeekOrigin.Begin);

Bước 3. Nhập XML kết quả vào tài liệu Word.

Ở đây chúng ta tiến hành như sau:

  • sao chép mẫu và mở bản sao
  • tìm xml tùy chỉnh cần thiết trong đó (tìm kiếm theo không gian tên “urn:Ghi chú cuộc họp”)
  • thay thế nội dung của thành phần bằng XML của chúng tôi

File.Copy(templateName, resultDocumentName, true ); sử dụng (var document = WordprocessingDocument.Open(resultDocumentName, true )) ( var xmlpart = document.MainDocumentPart.CustomXmlParts .Single(xmlPart => xmlPart.CustomXmlPropertiesPart.DataStoreItem.SchemaReferences.OfType ().Any(sr => sr.Uri.Value == "urn:MeetingNotes"!}