Skip to content

Commit 086360c

Browse files
authored
Made Kim's review changes (OfficeDev#71)
* Initial scaffolding for Excel tutorial. * Update yml metadata. * Test removing content from yaml file (support for href?). * Update yml to reference tutorial markdown files. * Set breadcrumb * Update Next Steps content in yml file. * Update tutorial breadcrumb. * Fix link. * Update breadcrumb. * Update breadcrumbs. * Update breadcrumbs. * Add top-level metadata; move intro and conclusion content into markdown files. * Fix broken link. * Move intro and conclusion back into yml file. * Remove intro and conclusion markdown files. * Minor update. * Add markdown content to yml file. * Remove markdown content from yml file. * Update TOC. * Move tutorial markdown into include files; update Excel Tutorial yml file to reference include files. * Fix broken links. * Update path to include files in tutorial yml file. * Try fix in tutorial yml file. * Try fix in tutorial yml file. * Try fix in tutorial yml file. * Fix broken link. * Fix broken link. * Update links to quickstart to point to the 'Any editor' tab of the quickstart, which contains info about sideloading. * Add sideload links to tutorial markdown. * Add sideload links to tutorial markdown files. * Update link text. * Update link text re sideloading on Windows in quickstarts. * Update intro in Create table step of tutorial. * Update intro for each step of the tutorial; add 'report issue' link to Introduction page. * Minor updates. * Split prereq and setup into its own step. * Fix issue in tutorial yml file. * Minor update. * Update durations in yml file. * Update breadcrumb. * Fix issue with breadcrumb. * Fix issue with breadcrumb. * Fix issue with breadcrumb. * Fix issue with breadcrumb. * Kim's review changes * Ctrl-C not Cntl-C
1 parent deaa16f commit 086360c

24 files changed

+896
-893
lines changed

.openpublishing.publish.config.json

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"Conceptual": "Content",
1313
"ManagedReference": "Content",
1414
"RestApi": "Content",
15+
"Tutorial": "Content",
1516
"LandingPage": "Content"
1617
},
1718
"build_entry_point": "docs",

docs/breadcrumb/toc.yml

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,11 @@
44
items:
55
- name: Add-ins
66
tocHref: /office/dev/add-ins/
7-
topicHref: /office/dev/add-ins/overview/office-add-ins
7+
topicHref: /office/dev/add-ins
8+
items:
9+
- name: Tutorials
10+
tocHref: /office/dev/add-ins
11+
items:
12+
- name: Excel add-in tutorial
13+
tocHref: /office/dev/add-ins/tutorials/excel-tutorial
14+
topicHref: /office/dev/add-ins/tutorials/excel-tutorial
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
In this step of the tutorial, you'll create a chart using data from the table that you created previously, and then format the chart.
2+
3+
## Chart table data
4+
5+
1. Open the project in your code editor.
6+
2. Open the file index.html.
7+
3. Below the `div` that contains the `sort-table` button, add the following markup:
8+
9+
```html
10+
<div class="padding">
11+
<button class="ms-Button" id="create-chart">Create Chart</button>
12+
</div>
13+
```
14+
15+
4. Open the app.js file.
16+
17+
5. Below the line that assigns a click handler to the `sort-chart` button, add the following code:
18+
19+
```js
20+
$('#create-chart').click(createChart);
21+
```
22+
23+
6. Below the `sortTable` function add the following function.
24+
25+
```js
26+
function createChart() {
27+
Excel.run(function (context) {
28+
29+
// TODO1: Queue commands to get the range of data to be charted.
30+
31+
// TODO2: Queue command to create the chart and define its type.
32+
33+
// TODO3: Queue commands to position and format the chart.
34+
35+
return context.sync();
36+
})
37+
.catch(function (error) {
38+
console.log("Error: " + error);
39+
if (error instanceof OfficeExtension.Error) {
40+
console.log("Debug info: " + JSON.stringify(error.debugInfo));
41+
}
42+
});
43+
}
44+
```
45+
46+
7. Replace `TODO1` with the following code. Note that in order to exclude the header row, the code uses the `Table.getDataBodyRange` method to get the range of data you want to chart instead of the `getRange` method.
47+
48+
```js
49+
const currentWorksheet = context.workbook.worksheets.getActiveWorksheet();
50+
const expensesTable = currentWorksheet.tables.getItem('ExpensesTable');
51+
const dataRange = expensesTable.getDataBodyRange();
52+
```
53+
54+
8. Replace `TODO2` with the following code. Note the following parameters:
55+
- The first parameter to the `add` method specifies the type of chart. There are several dozen types.
56+
- The second parameter specifies the range of data to include in the chart.
57+
- The third parameter determines whether a series of data points from the table should be charted rowwise or columnwise. The option `auto` tells Excel to decide the best method.
58+
59+
```js
60+
let chart = currentWorksheet.charts.add('ColumnClustered', dataRange, 'auto');
61+
```
62+
63+
9. Replace `TODO3` with the following code. Most of this code is self-explanatory. Note:
64+
- The parameters to the `setPosition` method specify the upper left and lower right cells of the worksheet area that should contain the chart. Excel can adjust things like line width to make the chart look good in the space it has been given.
65+
- A "series" is a set of data points from a column of the table. Since there is only one non-string column in the table, Excel infers that the column is the only column of data points to chart. It interprets the other columns as chart labels. So there will be just one series in the chart and it will have index 0. This is the one to label with "Value in €".
66+
67+
```js
68+
chart.setPosition("A15", "F30");
69+
chart.title.text = "Expenses";
70+
chart.legend.position = "right"
71+
chart.legend.format.fill.setSolidColor("white");
72+
chart.dataLabels.format.font.size = 15;
73+
chart.dataLabels.format.font.color = "black";
74+
chart.series.getItemAt(0).name = 'Value in €';
75+
```
76+
77+
## Test the add-in
78+
79+
80+
1. If the Git bash window, or Node.JS-enabled system prompt, from the previous stage tutorial is still open, enter Ctrl-C twice to stop the running web server. Otherwise, open a Git bash window, or Node.JS-enabled system prompt, and navigate to the **Start** folder of the project.
81+
82+
> [!NOTE]
83+
> Although the browser-sync server reloads your add-in in the task pane every time you make a change to any file, including the app.js file, it does not retranspile the JavaScript, so you must repeat the build command in order for your changes to app.js to take effect. In order to do this, you need to kill the server process in so that you can get a prompt to enter the build command. After the build, you restart the server. The next few steps carry out this process.
84+
85+
1. Run the command `npm run build` to transpile your ES6 source code to an earlier version of JavaScript that is supported by Internet Explorer (which is used under-the-hood by Excel to run Excel add-ins).
86+
2. Run the command `npm start` to start a web server running on localhost.
87+
4. Reload the task pane by closing it, and then on the **Home** menu, select **Show Taskpane** to reopen the add-in.
88+
5. If for any reason the table is not in the open worksheet, in the taskpane, choose **Create Table** and then **Filter Table** and **Sort Table** buttons, in either order.
89+
6. Choose the **Create Chart** button. A chart is created and only the data from the rows that have been filtered are included. The labels on the data points across the bottom are in the sort order of the chart; that is, merchant names in reverse alphabetical order.
90+
91+
![Excel tutorial - Create Chart](../images/excel-tutorial-create-chart.png)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
In this step of the tutorial, you'll programmatically test that your add-in supports the user's current version of Excel, add a table to a worksheet, populate the table with data, and format it.
2+
3+
## Code the add-in
4+
5+
1. Open the project in your code editor.
6+
2. Open the file index.html.
7+
3. Replace the `TODO1` with the following markup:
8+
9+
```html
10+
<button class="ms-Button" id="create-table">Create Table</button>
11+
```
12+
13+
4. Open the app.js file.
14+
5. Replace the `TODO1` with the following code. This code determines whether the user's version of Excel supports a version of Excel.js that includes all the APIs that this series of tutorials will use. In a production add-in, use the body of the conditional block to hide or disable the UI that would call unsupported APIs. This will enable the user to still make use of the parts of the add-in that are supported by their version of Excel.
15+
16+
```js
17+
if (!Office.context.requirements.isSetSupported('ExcelApi', 1.7)) {
18+
console.log('Sorry. The tutorial add-in uses Excel.js APIs that are not available in your version of Office.');
19+
}
20+
```
21+
22+
6. Replace the `TODO2` with the following code:
23+
24+
```js
25+
$('#create-table').click(createTable);
26+
```
27+
28+
7. Replace the `TODO3` with the following code. Note the following:
29+
- Your Excel.js business logic will be added to the function that is passed to `Excel.run`. This logic does not execute immediately. Instead, it is added to a queue of pending commands.
30+
- The `context.sync` method sends all queued commands to Excel for execution.
31+
- The `Excel.run` is followed by a `catch` block. This is a best practice that you should always follow.
32+
33+
```js
34+
function createTable() {
35+
Excel.run(function (context) {
36+
37+
// TODO4: Queue table creation logic here.
38+
39+
// TODO5: Queue commands to populate the table with data.
40+
41+
// TODO6: Queue commands to format the table.
42+
43+
return context.sync();
44+
})
45+
.catch(function (error) {
46+
console.log("Error: " + error);
47+
if (error instanceof OfficeExtension.Error) {
48+
console.log("Debug info: " + JSON.stringify(error.debugInfo));
49+
}
50+
});
51+
}
52+
```
53+
54+
8. Replace `TODO4` with the following code. Note:
55+
- The code creates a table by using `add` method of a worksheet's table collection, which always exists even if it is empty. This is the standard way that Excel.js objects are created. There are no class constructor APIs, and you never use a `new` operator to create an Excel object. Instead, you add to a parent collection object.
56+
- The first parameter of the `add` method is the range of only the top row of the table, not the entire range the table will ultimately use. This is because when the add-in populates the data rows (in the next step), it will add new rows to the table instead of writing values to the cells of existing rows. This is a more common pattern because the number of rows that a table will have is often not known when the table is created.
57+
- Table names must be unique across the entire workbook, not just the worksheet.
58+
59+
```js
60+
const currentWorksheet = context.workbook.worksheets.getActiveWorksheet();
61+
const expensesTable = currentWorksheet.tables.add("A1:D1", true /*hasHeaders*/);
62+
expensesTable.name = "ExpensesTable";
63+
```
64+
65+
9. Replace `TODO5` with the following code. Note:
66+
- The cell values of a range are set with an array of arrays.
67+
- New rows are created in a table by calling the `add` method of the table's row collection. You can add multiple rows in a single call of `add` by including multiple cell value arrays in the parent array that is passed as the second parameter.
68+
69+
```js
70+
expensesTable.getHeaderRowRange().values =
71+
[["Date", "Merchant", "Category", "Amount"]];
72+
73+
expensesTable.rows.add(null /*add at the end*/, [
74+
["1/1/2017", "The Phone Company", "Communications", "120"],
75+
["1/2/2017", "Northwind Electric Cars", "Transportation", "142.33"],
76+
["1/5/2017", "Best For You Organics Company", "Groceries", "27.9"],
77+
["1/10/2017", "Coho Vineyard", "Restaurant", "33"],
78+
["1/11/2017", "Bellows College", "Education", "350.1"],
79+
["1/15/2017", "Trey Research", "Other", "135"],
80+
["1/15/2017", "Best For You Organics Company", "Groceries", "97.88"]
81+
]);
82+
```
83+
84+
10. Replace `TODO6` with the following code. Note:
85+
- The code gets a reference to the **Amount** column by passing its zero-based index to the `getItemAt` method of the table's column collection.
86+
87+
> [!NOTE]
88+
> Excel.js collection objects, such as `TableCollection`, `WorksheetCollection`, and `TableColumnCollection` have an `items` property that is an array of the child object types, such as `Table` or `Worksheet` or `TableColumn`; but a `*Collection` object is not itself an array.
89+
90+
- The code then formats the range of the **Amount** column as Euros to the second decimal.
91+
- Finally, it ensures that the width of the columns and height of the rows is big enough to fit the longest (or tallest) data item. Notice that the code must get `Range` objects to format. `TableColumn` and `TableRow` objects do not have format properties.
92+
93+
```js
94+
expensesTable.columns.getItemAt(3).getRange().numberFormat = [['€#,##0.00']];
95+
expensesTable.getRange().format.autofitColumns();
96+
expensesTable.getRange().format.autofitRows();
97+
```
98+
99+
## Test the add-in
100+
101+
1. Open a Git bash window, or Node.JS-enabled system prompt, and navigate to the **Start** folder of the project.
102+
2. Run the command `npm run build` to transpile your ES6 source code to an earlier version of JavaScript that is supported by Internet Explorer (which is used under-the-hood by Excel to run Excel add-ins).
103+
3. Run the command `npm start` to start a web server running on localhost.
104+
4. Sideload the add-in by using one of the following methods:
105+
- Windows: [Sideload Office Add-ins on Windows](../testing/create-a-network-shared-folder-catalog-for-task-pane-and-content-add-ins.md)
106+
- Excel Online: [Sideload Office Add-ins in Office Online](../testing/sideload-office-add-ins-for-testing.md#sideload-an-office-add-in-on-office-online)
107+
- iPad and Mac: [Sideload Office Add-ins on iPad and Mac](../testing/sideload-an-office-add-in-on-ipad-and-mac.md)
108+
5. On the **Home** menu, choose **Show Taskpane**.
109+
6. In the taskpane, choose **Create Table**.
110+
111+
![Excel tutorial - Create Table](../images/excel-tutorial-create-table.png)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
In this step of the tutorial, you'll filter and sort the table that you created previously.
2+
3+
## Filter the table
4+
5+
1. Open the project in your code editor.
6+
2. Open the file index.html.
7+
3. Just below the `div` that contains the `create-table` button, add the following markup:
8+
9+
```html
10+
<div class="padding">
11+
<button class="ms-Button" id="filter-table">Filter Table</button>
12+
</div>
13+
```
14+
15+
4. Open the app.js file.
16+
17+
5. Just below the line that assigns a click handler to the `create-table` button, add the following code:
18+
19+
```js
20+
$('#filter-table').click(filterTable);
21+
```
22+
23+
6. Just below the `createTable` function, add the following function:
24+
25+
```js
26+
function filterTable() {
27+
Excel.run(function (context) {
28+
29+
// TODO1: Queue commands to filter out all expense categories except
30+
// Groceries and Education.
31+
32+
return context.sync();
33+
})
34+
.catch(function (error) {
35+
console.log("Error: " + error);
36+
if (error instanceof OfficeExtension.Error) {
37+
console.log("Debug info: " + JSON.stringify(error.debugInfo));
38+
}
39+
});
40+
}
41+
```
42+
43+
7. Replace `TODO1` with the following code. Note:
44+
- The code first gets a reference to the column that needs filtering by passing the column name to the `getItem` method, instead of passing its index to the `getItemAt` method as the `createTable` method does. Since users can move table columns, the column at a given index might change after the table is created. Hence, it is safer to use the column name to get a reference to the column. We used `getItemAt` safely in the preceding tutorial, because we used it in the very same method that creates the table, so there is no chance that a user has moved the column.
45+
- The `applyValuesFilter` method is one of several filtering methods on the `Filter` object.
46+
47+
```js
48+
const currentWorksheet = context.workbook.worksheets.getActiveWorksheet();
49+
const expensesTable = currentWorksheet.tables.getItem('ExpensesTable');
50+
const categoryFilter = expensesTable.columns.getItem('Category').filter;
51+
categoryFilter.applyValuesFilter(["Education", "Groceries"]);
52+
```
53+
54+
## Sort the table
55+
56+
1. Open the file index.html.
57+
2. Below the `div` that contains the `filter-table` button, add the following markup:
58+
59+
```html
60+
<div class="padding">
61+
<button class="ms-Button" id="sort-table">Sort Table</button>
62+
</div>
63+
```
64+
65+
3. Open the app.js file.
66+
67+
4. Below the line that assigns a click handler to the `filter-table` button, add the following code:
68+
69+
```js
70+
$('#sort-table').click(sortTable);
71+
```
72+
73+
5. Below the `filterTable` function add the following function.
74+
75+
```js
76+
function sortTable() {
77+
Excel.run(function (context) {
78+
79+
// TODO1: Queue commands to sort the table by Merchant name.
80+
81+
return context.sync();
82+
})
83+
.catch(function (error) {
84+
console.log("Error: " + error);
85+
if (error instanceof OfficeExtension.Error) {
86+
console.log("Debug info: " + JSON.stringify(error.debugInfo));
87+
}
88+
});
89+
}
90+
```
91+
92+
7. Replace `TODO1` with the following code. Note:
93+
- The code creates an array of `SortField` objects which has just one member since the add-in only sorts on the Merchant column.
94+
- The `key` property of a `SortField` object is the zero-based index of the column to sort-on.
95+
- The `sort` member of a `Table` is a `TableSort` object, not a method. The `SortField`s are passed the `TableSort` object's `apply` method.
96+
97+
```js
98+
const currentWorksheet = context.workbook.worksheets.getActiveWorksheet();
99+
const expensesTable = currentWorksheet.tables.getItem('ExpensesTable');
100+
const sortFields = [
101+
{
102+
key: 1, // Merchant column
103+
ascending: false,
104+
}
105+
];
106+
107+
expensesTable.sort.apply(sortFields);
108+
```
109+
110+
## Test the add-in
111+
112+
1. If the Git bash window, or Node.JS-enabled system prompt, from the previous stage tutorial is still open, enter Ctrl-C twice to stop the running web server. Otherwise, open a Git bash window, or Node.JS-enabled system prompt, and navigate to the **Start** folder of the project.
113+
114+
> [!NOTE]
115+
> Although the browser-sync server reloads your add-in in the task pane every time you make a change to any file, including the app.js file, it does not retranspile the JavaScript, so you must repeat the build command in order for your changes to app.js to take effect. In order to do this, you need to kill the server process in so that you can get a prompt to enter the build command. After the build, you restart the server. The next few steps carry out this process.
116+
117+
1. Run the command `npm run build` to transpile your ES6 source code to an earlier version of JavaScript that is supported by Internet Explorer (which is used under-the-hood by Excel to run Excel add-ins).
118+
2. Run the command `npm start` to start a web server running on localhost.
119+
4. Reload the task pane by closing it, and then on the **Home** menu, select **Show Taskpane** to reopen the add-in.
120+
5. If for any reason the table is not in the open worksheet, in the taskpane, choose **Create Table**.
121+
6. Choose the **Filter Table** and **Sort Table** buttons, in either order.
122+
123+
![Excel tutorial - Filter and Sort Table](../images/excel-tutorial-filter-and-sort-table.png)

0 commit comments

Comments
 (0)