title | description | ms.date | ms.topic | dev_langs | helpviewer_keywords | author | ms.author | manager | ms.technology | ms.workload | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Walkthrough: Create your first VSTO Add-in for Word |
Create an application-level Add-in for Microsoft Word. This feature is available to the application itself, regardless of which documents are open. |
02/02/2017 |
conceptual |
|
|
John-Hart |
johnhart |
jmartens |
office-development |
office |
Walkthrough: Create your first VSTO Add-in for Word
[!INCLUDE Visual Studio]
This introductory walkthrough shows you how to create a VSTO Add-in for Microsoft Office Word. The features that you create in this kind of solution are available to the application itself, regardless of which documents are open.
[!INCLUDEappliesto_wdallapp]
This walkthrough illustrates the following tasks:
-
Creating a Word VSTO Add-in project.
-
Writing code that uses the object model of Word to add text to a document when it is saved.
-
Building and running the project to test it.
-
Cleaning up the completed project so that the VSTO Add-in no longer runs automatically on your development computer.
[!INCLUDEnote_settings_general]
Prerequisites
You need the following components to complete this walkthrough:
-
[!INCLUDEvsto_vsprereq]
-
Microsoft Word
Create the project
To create a new Word VSTO Add-in project in Visual Studio
-
Start [!INCLUDEvsprvs].
-
On the File menu, point to New, and then click Project.
-
In the templates pane, expand Visual C# or Visual Basic, and then expand Office/SharePoint.
-
Under the expanded Office/SharePoint node, select the Office Add-ins node.
-
In the list of project templates, select a Word VSTO Add-in project.
-
In the Name box, type FirstWordAddIn.
-
Click OK.
[!INCLUDEvsprvs] creates the FirstWordAddIn project and opens the ThisAddIn code file in the editor.
Write code to add text to the saved document
Next, add code to the ThisAddIn code file. The new code uses the object model of Word to add boilerplate text to each saved document. By default, the ThisAddIn code file contains the following generated code:
-
A partial definition of the
ThisAddIn
class. This class provides an entry point for your code and provides access to the object model of Word. For more information, see Program VSTO Add-ins. The remainder of theThisAddIn
class is defined in a hidden code file that you should not modify. -
The
ThisAddIn_Startup
andThisAddIn_Shutdown
event handlers. These event handlers are called when Word loads and unloads your VSTO Add-in. Use these event handlers to initialize your VSTO Add-in when it is loaded, and to clean up resources used by your VSTO Add-in when it is unloaded. For more information, see Events in Office projects.
To add a paragraph of text to the saved document
-
In the ThisAddIn code file, add the following code to the
ThisAddIn
class. The new code defines an event handler for the xref:Microsoft.Office.Interop.Word.ApplicationEvents4_Event.DocumentBeforeSave event, which is raised when a document is saved.When the user saves a document, the event handler adds new text at the start of the document.
C#
:::code language=»csharp» source=»../vsto/codesnippet/CSharp/FirstWordAddIn/ThisAddIn.cs» id=»Snippet1″:::
VB
:::code language=»vb» source=»../vsto/codesnippet/VisualBasic/FirstWordAddIn/ThisAddIn.vb» id=»Snippet1″:::
[!NOTE]
This code uses an index value of 1 to access the first paragraph in the xref:Microsoft.Office.Interop.Word._Document.Paragraphs%2A collection. Although Visual Basic and Visual C# use 0-based arrays, the lower array bounds of most collections in the Word object model is 1. For more information, see Write code in Office solutions. -
If you are using C#, add the following required code to the
ThisAddIn_Startup
event handler. This code is used to connect theApplication_DocumentBeforeSave
event handler with the xref:Microsoft.Office.Interop.Word.ApplicationEvents4_Event.DocumentBeforeSave event.:::code language=»csharp» source=»../vsto/codesnippet/CSharp/FirstWordAddIn/ThisAddIn.cs» id=»Snippet2″:::
To modify the document when it is saved, the previous code examples use the following objects:
-
The
Application
field of theThisAddIn
class. TheApplication
field returns a xref:Microsoft.Office.Interop.Word.Application object, which represents the current instance of Word. -
The
Doc
parameter of the event handler for the xref:Microsoft.Office.Interop.Word.ApplicationEvents4_Event.DocumentBeforeSave event. TheDoc
parameter is a xref:Microsoft.Office.Interop.Word.Document object, which represents the saved document. For more information, see Word object model overview.
Test the project
To test the project
-
Press F5 to build and run your project.
When you build the project, the code is compiled into an assembly that is included in the build output folder for the project. Visual Studio also creates a set of registry entries that enable Word to discover and load the VSTO Add-in, and it configures the security settings on the development computer to enable the VSTO Add-in to run. For more information, see Build Office solutions.
-
In Word, save the active document.
-
Verify that the following text is added to the document.
This text was added by using code.
-
Close Word.
Clean up the project
When you finish developing a project, remove the VSTO Add-in assembly, registry entries, and security settings from your development computer. Otherwise, the VSTO Add-in will continue to run every time that you open Word on your development computer.
To clean up the completed project on your development computer
- In Visual Studio, on the Build menu, click Clean Solution.
Next steps
Now that you have created a basic VSTO Add-in for Word, you can learn more about how to develop VSTO Add-ins from these topics:
-
General programming tasks that you can perform in VSTO Add-ins: Program VSTO Add-ins.
-
Programming tasks that are specific to Word VSTO Add-ins: Word solutions.
-
Using the object model of Word: Word object model overview.
-
Customizing the UI of Word, for example, by adding a custom tab to the Ribbon or creating your own custom task pane: Office UI customization.
-
Building and debugging VSTO Add-ins for Word: Build Office solutions.
-
Deploying VSTO Add-ins for Word: Deploy an Office solution.
See also
- Office solutions development overview (VSTO)
- Word solutions
- Program VSTO Add-ins
- Word object model overview
- Office UI customization
- Build Office solutions
- Deploy an Office solution
- Office project templates overview
The C# programming language includes capabilities that make working with Microsoft Office API objects easier. With the advent of named and optional arguments, introduction of the dynamic type in .NET, and the ability to pass arguments to the reference parameters in COM methods, C# 4.0 quickly became the language of choice for working with COM and Interop objects.
This article talks about office interop objects in C# and how you can use them to interact with Microsoft Word and Microsoft Excel. Code examples are also provided to illustrate the concepts covered.
Prerequisites for working with Interop Objects
Visual Studio 2019 or Visual Studio 2022 must be installed on your computer to work with the code samples demonstrated in this C# tutorial. In this example, we will be using Visual Studio 2022. If you don’t have it installed in your computer, you can download it from here.
As of this writing, Visual Studio 2022 RC 2 has been released. You should also have Microsoft Office Excel 2007 or Microsoft Office Word 2007 (or their later versions) installed on your computer.
Read: Code Refactoring Tips for C#.
How to Create a New Console Application in Visual Studio
In this section we will examine how we can create a new console application project in Visual Studio 2022. Assuming Visual Studio 2022 is installed on your system, adhere to the steps given below to create a new Console Application project:
- Start the Visual Studio 2022 IDE.
- Click on “Create new project.”
- In the “Create new project” page, select C# in the language drop down list, Windows from the Platforms list and Console from the “Project types” list.
- Select Console App (.NET Framework) from the project templates displayed.
- Click Next.
- In the “Configure your new project” screen, specify the project’s name and the location where you would want the project to be created.
- Before you move on to the next screen, you can optionally select the “Place solution and project in the same directory” checkbox.
- Click Next.
- In the Additional Information screen, specify the Framework version you would like to use. We will use .NET Framework 4.8 in this example.
- Click Create to complete the process.
This will create a new .NET Framework Console application project in Visual Studio 2022. We will use this project in the sections that follow.
Install NuGet Packages
Install the following libraries from NuGet using the NuGet Package Manager or from the NuGet Package Manager Console:
Microsoft.Office.Interop.Word Microsoft.Office.Interop.Excel
Read: Working with C# Math Operators.
How to Program Office Interop Objects in C#
In this section we will examine how to work with Office Interop objects and use them to connect to Microsoft Word and Excel and read/write data.
You must add the following using directives in your program for working with Word and Excel respectively when using Office interop objects:
using Microsoft.Office.Interop.Excel; using Microsoft.Office.Interop.Word;
Working with Excel Interop Objects in C#
To begin, create a new Excel document named Test.xslx as a sample Excel file present in the root directory of the D:> drive. We will use this file in the following example.
You should create an instance of the Application class pertaining to the Microsoft.Office.Interop.Excel library for communicating with Excel. To do this, write the following C# code:
Application excelApplication = new Application();
The next step is to create an instance of the Workbook class to access a Workbook in Excel. You can create an instance of Workbook using the following code:
Workbook excelWorkBook = excel.Workbooks.Open(@"D:Test.xslx");
To read the name of the workbook, you can use the Name property of the workbook instance as shown in the code snippet given below:
string workbookName = excelWorkBook.Name;
The following code listing illustrates how you can display the value of the first cell of the first worksheet of the Excel document:
int worksheetcount = excelWorkBook.Worksheets.Count; if (worksheetcount > 0) { Worksheet worksheet = (Worksheet) excelWorkBook.Worksheets[1]; string worksheetName = worksheet.Name; var data = ((Range) worksheet.Cells[row, column]).Value; Console.WriteLine(data); } else { Console.WriteLine("No worksheets available"); }
Here’s the complete code listing for your reference:
using Microsoft.Office.Interop.Excel; using Microsoft.Office.Interop.Word; using System; using System.Runtime.InteropServices; namespace OfficeInteropDemoApp { class Program { static void Main(string[] args) { string filename = @"D:Test.xlsx"; DisplayExcelCellValue(filename, 1, 1); Console.Read(); } static void DisplayExcelCellValue(string filename, int row, int column) { Microsoft.Office.Interop.Excel.Application excelApplication = null; try { excelApplication = new Microsoft.Office.Interop.Excel.Application(); Workbook excelWorkBook = excelApplication.Workbooks.Open(filename); string workbookName = excelWorkBook.Name; int worksheetcount = excelWorkBook.Worksheets.Count; if (worksheetcount > 0) { Worksheet worksheet = (Worksheet)excelWorkBook.Worksheets[1]; string firstworksheetname = worksheet.Name; var data = ((Microsoft.Office.Interop.Excel.Range) worksheet.Cells[row, column]).Value; Console.WriteLine(data); } else { Console.WriteLine("No worksheets available"); } } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { if (excelApplication != null) { excelApplication.Quit(); Marshal.FinalReleaseComObject(excelApplication); } } } } }
Refer to the code listing given above. Note, the finally block of the DisplayExcelCellValue method. The Quit method is called on the Excel application instance to stop the application. Finally, a call to Marshall.FinalReleaseComObject sets the reference counter of the Excel application instance to 0.
The following code listing illustrates how you can create a new Excel document using Office Interop in C#. Note how a new workbook has been created:
static void CreateExcelDocument() { Microsoft.Office.Interop.Excel.Application excelApplication = null; try { excelApplication = new Microsoft.Office.Interop.Excel.Application(); Workbook excelWorkBook = excelApplication.Workbooks.Add(); Worksheet worksheet = (Worksheet) excelWorkBook.Worksheets[1]; worksheet.Cells[1, 1] = "Product Id"; worksheet.Cells[1, 2] = "Product Name"; worksheet.Cells[2, 1] = "1"; worksheet.Cells[2, 2] = "Lenovo Laptop"; worksheet.Cells[3, 1] = "2"; worksheet.Cells[3, 2] = "DELL Laptop"; excelWorkBook.SaveAs(@"D:Test.xls"); } catch(Exception ex) { Console.WriteLine(ex.Message); } finally { if (excelApplication != null) { excelApplication.Quit(); Marshal.FinalReleaseComObject(excelApplication); } } }
When you run this code, a new Excel document will be created at the path specified with the following content inside:
Read: Working with Strings in C#.
Working with Word Interop Objects in C#
To work with Microsoft Word, you would need to create an instance of Microsoft.Office.Interop.Word.Application. Like Excel, this instance would be used to communicate with a Word document.
Microsoft.Office.Interop.Word.Application wordApplication = new Microsoft.Office.Interop.Word.Application();
The next step is to create a document instance using the Documents property of the Microsoft.Office.Interop.Word.Application instance we just created, as shown in the C# code snippet given below:
wordApplication.Documents.Add();
Next, you can create a paragraph and add some text to it using the as shown in the code snippet shown below:
var paragraph = document.Paragraphs.Add(); paragraph.Range.Text = "This is a sample text to demonstrate how Interop works...";
Then you can save the Word document using this code:
wordApplication.ActiveDocument.SaveAs(@"D:Test.doc", WdSaveFormat.wdFormatDocument);
Here is the complete code listing showing how to work with Microsoft Word Interop Objects in C# for your reference:
using Microsoft.Office.Interop.Excel; using Microsoft.Office.Interop.Word; using System; using System.Runtime.InteropServices; namespace OfficeInteropDemoApp { class Program { static void Main(string[] args) { string filename = @"D:Test.doc"; CreateWordDocument(filename); Console.Read(); } static void CreateWordDocument(string filename) { Microsoft.Office.Interop.Word.Application wordApplication = null; try { wordApplication = new Microsoft.Office.Interop.Word.Application(); var document = wordApplication.Documents.Add(); var paragraph = document.Paragraphs.Add(); paragraph.Range.Text = "This is a sample text to demonstrate how Interop works..."; wordApplication.ActiveDocument.SaveAs(filename, WdSaveFormat.wdFormatDocument); document.Close(); } finally { if (wordApplication != null) { wordApplication.Quit(); Marshal.FinalReleaseComObject(wordApplication); } } } } }
To read a Word document and display each word of the document you can use the following C# code:
static void ReadWordDocument(string filename) { Microsoft.Office.Interop.Word.Application wordApplication = null; try { wordApplication = new Microsoft.Office.Interop.Word.Application(); Document document = wordApplication.Documents.Open(filename); int count = document.Words.Count; for (int i = 1; i <= count; i++) { string text = document.Words[i].Text; Console.WriteLine(text); } } catch(Exception ex) { Console.Write(ex.Message); } finally { if (wordApplication != null) { wordApplication.Quit(); Marshal.FinalReleaseComObject(wordApplication); } } }
Note how the Words property of the Word application instance has been used to retrieve the words contained in the document.
C# Interop Objects Tutorial
In this article we have examined how we can access Microsoft Office Interop objects using C#. Since there is still no support for working with Interop objects in .NET Core, we have created a .NET Framework Console Application in this example.
Table of Contents
- Introduction
- Building the Sample
You can download the source code from this link Source
Code Link
Introduction
The main purpose of this article is to explain how to create simple Excel and Microsoft Word Add-Ins using Visual
Studio Tools for Office (VSTO).
VSTO is available as an add-in tool with Microsoft Visual Studio. Using Visual Studio we can develop our own custom controls for Office tools like Excel, Word and and so on.In
our demo program We have used Visual Studio 2010 and Office 2007.
Building the Sample
This article explains a few basic things to create our own Custom Add-Ins for Excel and Word as follows.
1. Excel Add-Ins
- Add text to any Excel selected active Excel cell.
- Add an image to Excel from our Custom Control.
- Load data from a database and display the search result data in Excel.
2. Word Add-Ins
- Export Word to PDF.
- Add Image to Word Document.
- Add Table to Word document.
Description
Creating Excel Add-Ins
To create our own Custom Control Add-Ins for Excel.
Step 1
Create a new project and select Office 2007 Excel Add-In as in the following Image. Select your Project Folder and enter your Project Name.
Step 2
Now we can see that the Excel ThisAddIn.Cs file has been created in our project folder and we can find two default methods in this class as in the following image. “ThisAddIn_Startup”
In this event we can display our own custom Control Add-Ins to Excel. We can see the details in the code part.
Step 3
Add a new UserControl to your project to create your own Custom Excel Control Add-In.
Right-click your project->Click Add New Item->Add User Control and Name the control as you wish. Add all your Controls and design your user control depending on your requirement.
In our example,We are performing 3 types of actions in User Controls.
- Add Text: In this button click event I will insert the text from the Text box to the Active Selected Excel Cell. Using “Globals.ThisAddIn.Application.ActiveCell”
we can get the current active Excel cell. We store the result in an Excel range and now using the range, value and color we can set our own text and colors to the active Excel Cell.
private void btnAddText_Click(object sender, EventArgs e)
{
Excel.Range objRange = Globals.ThisAddIn.Application.ActiveCell;
objRange.Interior.Color = Color.Pink; //Active Cell back Color
objRange.Borders.Color = Color.Red;// Active Cell border Color
objRange.Borders.LineStyle = Excel.XlLineStyle.xlContinuous;
objRange.Value = txtActiveCellText.Text; //Active Cell Text Add
objRange.Columns.AutoFit();
}
2. Add Image: using
the Open File Dialog we can select our own image that needs to be added to the Excel file. Using the Excel.Shape we can add our selected image to the Excel file.
private void btnAddImage_Click(object sender, EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.FileName = "*";
dlg.DefaultExt = "bmp";
dlg.ValidateNames = true;
dlg.Filter = "Bitmap Image (.bmp)|*.bmp|Gif Image (.gif)|*.gif|JPEG Image (.jpeg)|*.jpeg|Png Image (.png)|*.png";
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Bitmap dImg = new Bitmap(dlg.FileName);
Excel.Shape IamgeAdd = Globals.ThisAddIn.Application.ActiveSheet.Shapes.AddPicture(dlg.FileName,
Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoCTrue,
20, 30, dImg.Width, dImg.Height);
}
System.Windows.Forms.Clipboard.Clear();
}
Search and bind Db Data to Excel: Now
we can create our own Custom Search control to be used in Excel to search our data from the database and bind the result to the Excel file.
Creating the table
-- Create Table ItemMaster in your SQL Server - This table will be used for search and bind result to excel.
CREATE
TABLE
[dbo].[ItemMasters](
[Item_Code] [
varchar
](20)
NOT
NULL
,
[Item_Name] [
varchar
](100)
NOT
NULL
)
-- insert sample data to Item Master table
INSERT
INTO
[ItemMasters] ([Item_Code],[Item_Name])
VALUES
(
'Item001'
,
'Coke'
)
INSERT
INTO
[ItemMasters] ([Item_Code],[Item_Name])
VALUES
(
'Item002'
,
'Coffee'
)
INSERT
INTO
[ItemMasters] ([Item_Code],[Item_Name])
VALUES
(
'Item003'
,
'Chiken Burger'
)
INSERT
INTO
[ItemMasters] ([Item_Code],[Item_Name])
VALUES
(
'Item004'
,
'Potato Fry'
)
In the button search click event we search for the data from the database and bind the result to an Excel cell using “Globals.ThisAddIn.Application.ActiveSheet.Cells”.
This will add the result to the active Excel sheet.
private
void
btnSearch_Click(object
sender, EventArgs e)
{
try
{
System.Data.DataTable dt =
new
System.Data.DataTable();
String ConnectionString =
"Data Source=YOURDATASOURCE;Initial Catalog=YOURDATABASENAME;User id = UID;password=password"
;
SqlConnection con =
new
SqlConnection(ConnectionString);
String Query =
" Select Item_Code,Item_Name FROM ItemMasters Where Item_Name LIKE '"
+ txtItemName.Text.Trim() +
"%'"
;
SqlCommand cmd =
new
SqlCommand(Query, con);
cmd.CommandType = System.Data.CommandType.Text;
System.Data.SqlClient.SqlDataAdapter sda =
new
System.Data.SqlClient.SqlDataAdapter(cmd);
sda.Fill(dt);
if
(dt.Rows.Count <= 0)
{
return
;
}
Globals.ThisAddIn.Application.ActiveSheet.Cells.ClearContents();
Globals.ThisAddIn.Application.ActiveSheet.Cells[1, 1].Value2 =
"Item Code"
;
Globals.ThisAddIn.Application.ActiveSheet.Cells[1, 2].Value2 =
"Item Name"
;
for
(
int
i = 0; i <= dt.Rows.Count - 1; i++)
{
Globals.ThisAddIn.Application.ActiveSheet.Cells[i + 2, 1].Value2 = dt.Rows[i][0].ToString();
Globals.ThisAddIn.Application.ActiveSheet.Cells[i + 2, 2].Value2 = dt.Rows[i][1].ToString();
}
}
catch
(Exception ex)
{
}
}
Step 4
Now we have created our own User Control to be added to our Excel Add-Ins. To add this user control to our Excel Add-In as we have already seen that the Excel Addin class “ThisAddIn.Cs” has start and stop events. Using
the Office “CustomTaskpane” we can add our user control to Excel as an Add-In as in the following.
private
Microsoft.Office.Tools.CustomTaskPane customPane;
private
void
ThisAddIn_Startup(object
sender, System.EventArgs e)
{
ShowShanuControl();
}
public
void
ShowShanuControl()
{
var txtObject =
new
ShanuExcelADDIn();
customPane =
this
.CustomTaskPanes.Add(txtObject,
"Enter Text"
);
customPane.Width = txtObject.Width;
customPane.Visible =
true
;
}
Step 5
Run your program and now we can see our user control has been added in the Excel File as an Add-In.
Next we will see how to create Add-Ins for Word Documents using a Ribbon Control.
Creating Word Add-Ins:
In my example I have used Visual Studio 2010 and Office 2007.
The following describes how to create our own Custom Control Add-Ins for Word.
Step 1
Create a new project and select Office 2007 Word AddIn as in the following Image. Select your Project Folder and enter your Project Name.
Step 2
Add a new Ribbon Control to your project to create your own Word Control Add-In.
Right-click your project then click Add New Item -> Add Ribbon Control and name the control as you wish.
Add all your controls and design your user control depending on your requirements. By default in our Ribbon Control we can see a “RibbonGroup”. We can add all our controls to the Ribbon Group. Here
in my example I have changed the Group Label Text to “SHANU Add-In”. I have added three Ribbon Button Controls to the group. We can add an image to the Ribbon Button Controls and set the properties of the Button Control Size as “RibbobControlSizeLarge”.
Here I have added three Button Controls for export the Word as a PDF, add an image to Word and add a table to the Word file.
Step 3
Export to PDF File Button Click.
Using the “Globals.ThisAddIn.Application.ActiveDocument.ExportAsFixedFormat” we can save the Word document to the PDF file. I have used the Save file dialog to save the PDF file into our selected path.
private
void
btnPDF_Click(object
sender, RibbonControlEventArgs e)
{
SaveFileDialog dlg =
new
SaveFileDialog();
dlg.FileName =
"*"
;
dlg.DefaultExt =
"pdf"
;
dlg.ValidateNames =
true
;
if
(dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Globals.ThisAddIn.Application.ActiveDocument.ExportAsFixedFormat(dlg.FileName, word.WdExportFormat.wdExportFormatPDF, OpenAfterExport:
true
);
}
}
Step 4
Here we will add an image to Word. Using the Open File Dialog we can select our own image to be added to the Word file. Using the “Globals.ThisAddIn.Application.ActiveDocument.Shapes.AddPicture” method we can add our
selected image to the Word file.
private
void
btnImage_Click(object
sender, RibbonControlEventArgs e)
{
OpenFileDialog dlg =
new
OpenFileDialog();
dlg.FileName =
"*"
;
dlg.DefaultExt =
"bmp"
;
dlg.ValidateNames =
true
;
dlg.Filter =
"Bitmap Image (.bmp)|*.bmp|Gif Image (.gif)|*.gif|JPEG Image (.jpeg)|*.jpeg|Png Image (.png)|*.png"
;
if
(dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Globals.ThisAddIn.Application.ActiveDocument.Shapes.AddPicture(dlg.FileName);
}
}
Step 5
Here we will add a table to Word. Using the “Globals.ThisAddIn.Application.ActiveDocument.Tables” method we can add a table to the Word file. In my example I have created a table with 4 columns and 3 rows.
private
void
button1_Click(object
sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.Application.ActiveDocument.Tables.Add(Globals.ThisAddIn.Application.ActiveDocument.Range(0, 0), 3, 4);
.ThisAddIn.Application.ActiveDocument.Tables[1].Range.Shading.BackgroundPatternColor = Microsoft.Office.Interop.Word.WdColor.wdColorSeaGreen;
Globals.ThisAddIn.Application.ActiveDocument.Tables[1].Range.Font.Size = 12;
Globals.ThisAddIn.Application.ActiveDocument.Tables[1].Rows.Borders.Enable = 1;
}
Step 6
Run your program and now you will see your own Ribbon Control has been added to the Word file as an Add-In.
You can download the source code from this link Source
Code Link
Задача: вывести данные в документ Word. На самом деле это очень большая и необъятная тема, примерно как сам Word, 90% возможностей которого не используются обычными пользователями. Сузим до более простой и чаще встречающейся на практике задачи, с которой в своей время пришлось столкнуться мне самому: надо вывести красивую справку, договор, отчет или иной документ Word с добавлением данных из кода C#. Само собой должны поддерживаться версии Word до 2007, так что о новых форматах файлов придется забыть.
Для начала вспомним, что в Word есть такая замечательная вещь как шаблоны. Соответственно большую часть сложного оформления можно вынести в них и из кода открывать шаблон и вставлять данные в нужные места. Для начала ограничимся простыми строками (типовая задача в крупных предприятиях — вставка дат, цифр, фио и тому подобных вещей, договор на сумму такую-то, от такой-то даты с фио таким-то с параметрами объекта такими-то).
Задача на текущую статью: открыть из кода C# шаблон Word и что-то в него вставить. Шаблон в формате .dot приготовим заранее, в том же самом ворде. Для связи с ним будем использовать механизм COM Interoperability (сокращенно Interop), то есть запускать отдельный exe-процесс самого Word и через специальный интерфейс управлять им. Интерфейсы слава богу есть и находятся они в специальных библиотеках, поставляемых вместе с Office, но документация по ним крайне невнятная, поведение местами очень странное и не логичное. В версиях Visual Studio 2010 и выше возможности программирования Office расширены, но текущее руководство действительно и для 2008 студии.
Нам надо
1. Подключить нужные библиотеки
2. Открыть шаблон Word
3. Найти в нем нужное место
4. Вставить в него строку с информацией
1. Проект в студии у нас уже должен быть. В разделе Ссылки/References кликаем правой кнопкой, идем в «Добавить ссылку» и ищем Microsoft.Office.Interop.Word. В параметрах добавленной библиотеки ставим true в Копировать локально/Copy local, так как библиотеку надо копировать вместе с исполняемыми файлами проекта.
В код добавляем соответствующие using
using Word = Microsoft.Office.Interop.Word; using System.Reflection;
2. Теперь вам предстоит провести много времени с замечательным интерфейсом Word, который представляет сам текстовый редактор и его потроха в виде разнообразных обьектов. Сейчас важны два — Application и Document. Переменные для них по ряду не очевидных причин лучше объявлять через интерфейсы.
Word._Application application; Word._Document document;
Так же почти все функции Word требуют объектных параметров, даже если внутри них сидят простые строки и логические значения, так что лучше заранее сделать несколько оберток
Object missingObj = System.Reflection.Missing.Value; Object trueObj = true; Object falseObj = false;
Чтобы запустить Word и открыть в нем шаблон с диска (путь известен), потребуется примерно такой код
//создаем обьект приложения word application = new Word.Application(); // создаем путь к файлу Object templatePathObj = "путь к файлу шаблона";; // если вылетим не этом этапе, приложение останется открытым try { document = application.Documents.Add(ref templatePathObj, ref missingObj, ref missingObj, ref missingObj); } catch (Exception error) { document.Close(ref falseObj, ref missingObj, ref missingObj); application.Quit(ref missingObj, ref missingObj, ref missingObj); document = null; application = null; throw error; } _application.Visible = true;
Принципиально важны два момента
1. Мы создаем неуправляемый ресурс, который не соберет сборщик мусора — отдельный процесс в памяти с приложением Word, если мы его не закроем и не выведем на экран, он так и останется там висеть до выключения компьютера. Более того такие ворды могут накапливаться незаметно для пользователя, программист-то еще прибьет их вручную. Заботиться о высвобождения неуправляемого ресурса должен программист.
2. По умолчанию Word запускается невидимым, на экран его выводим мы.
Для начала рассмотрим самый простой и примитивный вариант — поиск и замена строки в документе Word. Некоторые программисты так и работают — ставят в шаблон текстовую метку вроде @@nowDate и заменяют ее на нужное значение.
Пришло время познакомится с фундаментом работы с Word — великим и ужасным объектом Range. Его суть сложно описать словами -это некоторый произвольный кусок документа, диапазон (range), который может включать в себя все что угодно — от пары символов, до таблиц, закладок и прочих интересных вещей. Не стоит путать его с Selection — куском документа, выделенным мышкой, который само собой можно конвертировать в Range. Соотвественно нам надо получить Range для всего документа, найти нужную строку внутри него, получить Range для этой строки и уже внутри этого последнего диапазона заменить текст на требуемый. И не стоит забывать, что документ может иметь сложную структуру с колонтитулами и прочей ересью, возможный универсальный метод для замены всех вхождений данной строки:
// обьектные строки для Word object strToFindObj = strToFind; object replaceStrObj = replaceStr; // диапазон документа Word Word.Range wordRange; //тип поиска и замены object replaceTypeObj; replaceTypeObj = Word.WdReplace.wdReplaceAll; // обходим все разделы документа for (int i = 1; i <= _document.Sections.Count; i++) { // берем всю секцию диапазоном wordRange = _document.Sections[i].Range; /* Обходим редкий глюк в Find, ПРИЗНАННЫЙ MICROSOFT, метод Execute на некоторых машинах вылетает с ошибкой "Заглушке переданы неправильные данные / Stub received bad data" Подробности: http://support.microsoft.com/default.aspx?scid=kb;en-us;313104 // выполняем метод поиска и замены обьекта диапазона ворд wordRange.Find.Execute(ref strToFindObj, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref replaceStrObj, ref replaceTypeObj, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing); */ Word.Find wordFindObj = wordRange.Find; object[] wordFindParameters = new object[15] { strToFindObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, replaceStrObj, replaceTypeObj, _missingObj, _missingObj, _missingObj, _missingObj }; wordFindObj.GetType().InvokeMember("Execute", BindingFlags.InvokeMethod, null, wordFindObj, wordFindParameters); }
Редкий глюк подробно описан здесь.
На самом деле это не самый лучший метод для вставки информации в документ, так как могут возникнуть сложности с уникальными именами для текстовых меток (если текст одной входит в начало другой, данный метод найдет ее и заменит), их совпадением с произвольным текстом и так далее.
Даже если нам надо найти (и например отформатировать) именно строку с текстом внутри документа, лучше всего выдать наружу найденный Range и уже с ним производить разные злодеяния. Получим примерно такой метод:
object stringToFindObj = stringToFind; Word.Range wordRange; bool rangeFound; //в цикле обходим все разделы документа, получаем Range, запускаем поиск // если поиск вернул true, он долже ужать Range до найденное строки, выходим и возвращаем Range // обходим все разделы документа for (int i = 1; i <= _document.Sections.Count; i++) { // берем всю секцию диапазоном wordRange = _document.Sections[i].Range; /* // Обходим редкий глюк в Find, ПРИЗНАННЫЙ MICROSOFT, метод Execute на некоторых машинах вылетает с ошибкой "Заглушке переданы неправильные данные / Stub received bad data" Подробности: http://support.microsoft.com/default.aspx?scid=kb;en-us;313104 // выполняем метод поиска и замены обьекта диапазона ворд rangeFound = wordRange.Find.Execute(ref stringToFindObj, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing); */ Word.Find wordFindObj = wordRange.Find; object[] wordFindParameters = new object[15] { stringToFindObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj }; rangeFound = (bool)wordFindObj.GetType().InvokeMember("Execute", BindingFlags.InvokeMethod, null, wordFindObj, wordFindParameters); if (rangeFound) { return wordRange; } } // если ничего не нашли, возвращаем null return null;
Простейшее решение проблемы уникальности текста (нужно нам найти Range слова Word, но внутри всего документа оно встречается десятки раз) — искать строку внутри строки, сначала найти уникальную строку, потом не уникальную внутри нее, неэстетично, но дешево, надежно и практично.
// оформляем обьектные параметры object stringToFindObj = stringToFind; bool rangeFound; /* Обходим редкий глюк в Find, ПРИЗНАННЫЙ MICROSOFT, метод Execute на некоторых машинах вылетает с ошибкой "Заглушке переданы неправильные данные / Stub received bad data" http://support.microsoft.com/default.aspx?scid=kb;en-us;313104 rangeFound = containerRange.Find.Execute(ref stringToFindObj, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing); */ Word.Find wordFindObj = containerRange.Find; object[] wordFindParameters = new object[15] { stringToFindObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj }; rangeFound = (bool)wordFindObj.GetType().InvokeMember("Execute", BindingFlags.InvokeMethod, null, wordFindObj, wordFindParameters); if (rangeFound) { return containerRange; } else { return null; }
Если строку надо просто заменить, то сойдет простейшее
_range.Text = "Это текст заменит содержимое Range";
Но так как Range является универсальный контейнером для любого куска документа Word, то его возможности неизмеримо шире, часть их будет рассмотрена в дальнейших заметках.
Если нам надо просто встать в начало документа (и что-то вставить уже туда):
object start = 0; object end = 0; _currentRange = _document.Range(ref start, ref end);
Сохранить документ на диск можно следующим образом
Object pathToSaveObj = pathToSaveString; _document.SaveAs(ref pathToSaveObj, Word.WdSaveFormat.wdFormatDocument, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj);
- Работаем с MS Word из C#, часть 0, класс и тестовый проект-пример WinForms
- Работаем с MS Word из C#, часть 1. Открываем шаблон, ищем текст внутри документа
- Работаем с MS Word из C#, часть 2. Вставляем текст на закладку и форматируем
- Работаем с MS Word из C#, часть 3. Работа с таблицами
- Работаем с MS Word из C#, часть 4. Обьединяем несколько файлов в один, считаем количество страниц
- Microsoft.Office.Interop.Word Namespace
- Range Interface
- Remove From My Forums
-
Question
-
I have read a lot way to solve this problem, but still can’t find it.
My pc is win10 & visual studio 2017.
I can find it in the C:Windowsassembly. Does it means I have installed?
Answers
-
Did you install the Visual Studio Tools for Office?
— Wayne
-
Marked as answer by
Chien-Wei
Thursday, September 13, 2018 4:18 AM
-
Marked as answer by
All replies
-
Hi,
.net 4.0 or later version added reference, if it is not 4.0 or above, there may not be this, you can download a Microsoft.Office.Interop.Word.dll by yourself.
In your project, right-click on «References» and select «Add» .
Imports Microsoft.Office.Interop.Word
Best Regards,
Alex
MSDN Community Support Please remember to click «Mark as Answer» the responses that resolved your issue, and to click «Unmark as Answer» if not. This can be beneficial to other community members reading this thread. If you have any
compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.-
Marked as answer by
Chien-Wei
Wednesday, September 12, 2018 11:50 AM -
Unmarked as answer by
Chien-Wei
Wednesday, September 12, 2018 11:50 AM
-
Marked as answer by
-
With VS 2015, Office 2016, I add the Object Library :
-
There are times when an assembly will not show up and you need to browse for them. Browse under were the bold parts reflect which version of Office is installed.
C:Program Files (x86)Microsoft Visual Studio 14.0Visual Studio Tools for OfficePIAOffice15.
You can also add them to «Custom Component Set» in Object Browser (the default hot key is F2). Once added select that library and press the button where the arrow is indicating.
I this for all the ones shown as I use them often.
Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via
my MSDN profile but will not answer coding question on either.
VB Forums — moderator
-
HI,Alex-Li-MSFT
I check my project is .net4.5.2 , but I can’t find the microsoft.office.interop.word in the VS assemblies.
Is it any possible that my office is o365 cause the problem?
Thanks for your reply.
-
Edited by
Chien-Wei
Wednesday, September 12, 2018 11:51 AM
-
Edited by
-
Hi, Casorix31
I have add this com already, but there are some code error.
I try to add a table in the document,but error shows tables are not the member of document.
I search this problem and they tell me I need to add microsoft.office.interop.word first.
Thanks for your reply.
-
Edited by
Chien-Wei
Wednesday, September 12, 2018 11:52 AM
-
Edited by
-
Did you install the Visual Studio Tools for Office?
— Wayne
-
Marked as answer by
Chien-Wei
Thursday, September 13, 2018 4:18 AM
-
Marked as answer by
-
Hi, WayneAKing
Thanks for your help, I finally find it.
-
Hi,
I am glad you have got your solution, we appreciated you shared us your solution and mark it as an answer.
Best Regards,
Alex
MSDN Community Support Please remember to click «Mark as Answer» the responses that resolved your issue, and to click «Unmark as Answer» if not. This can be beneficial to other community members reading this thread. If you have any
compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.