OfficeDev / office-js

A repo and NPM package for Office.js, corresponding to a copy of what gets published to the official "evergreen" Office.js CDN, at https://appsforoffice.microsoft.com/lib/1/hosted/office.js.
https://learn.microsoft.com/javascript/api/overview
Other
676 stars 95 forks source link

how to set the list numbering format of a list style #4961

Open zeratul1215 opened 1 month ago

zeratul1215 commented 1 month ago

we can set the numbering format of a list style manaually in the word, but is there any way that I can use office.js to set the numbering format by code? I used const style = context.document.addStyle(newStyleName, Word.StyleType.list); to create a new list style, and when I print out the listLevels of the new style, it gives me an undefined result. I want to set this style's numbering format as. for example, "a.b.c", the first two numbering "a.b" are based on the father list it belongs to and the last numbering "c" just shows this is the "c"th list paragraph using this format Consecutively. Is it possible to implement a function like this?

AlexJerabek commented 1 month ago

Thanks for the question @zeratul1215.

@ElizabethSamuel-MSFT, could you please verify if this scenario is possible with the Word JS APIs?

ElizabethSamuel-MSFT commented 1 month ago

@zeratul1215 Try to set the style.listTemplate.outlineNumbered property to true. To configure the formatting for list levels in a list style, access the style.listTemplate.listLevels property and for each list level you care about, set the appropriate properties of its ListLevel object.

Let us know if this helped or if you have further questions.

Thanks.

zeratul1215 commented 1 month ago

thank you for your answer, I will try it, but I noticed that there is a function in the word that, you can create multilevel list and, link each level of the multilevel list to a style, and I noticed that there is a property in the listlevel class called "linked style ", so is it possible to create a new multilevel list format first and link each level to a style by code? I think this approach is more suitable for my product

zeratul1215 commented 1 month ago

wait, I suddenly realized that: Is that "create multilevel list" function in the word just creating a list style in the code?

zeratul1215 commented 1 month ago

after I try to console.log the list level of a newly created list style, the items property in it is undefined, does it mean that the I need to add new list levels into this list style by code? if so, how can I do it

ElizabethSamuel-MSFT commented 1 month ago

@zeratul1215 Thanks for providing more info. Can you add a screenshot showing an example of what this could look like in a Word document?

Thanks.

zeratul1215 commented 1 month ago

屏幕截图 2024-09-19 063057 屏幕截图 2024-09-19 063143

zeratul1215 commented 1 month ago

first I set that "link level to style" property to a specified style in word and then when I set to use the style, there will be a automatic numbering

ElizabethSamuel-MSFT commented 1 month ago

To your question: Is that "create multilevel list" function in the word just creating a list style in the code? - The answer is no. The "Create multilevel list" UI formats the current list you're working on in your document (this can also be done through JS - e.g., see the Organize list sample). Through JS, you can create a list style that can then be applied to format a multilevel list, including the automatic numbering. This ability to create a list style maps to the "Define New List Style" function in the Word UI.

image

image

Once you've configured your custom list style, you can make the style available in other documents and on other machines by having your add-in call Word.Document.importStylesFromJson with a JSON object that represents your custom list style.

As you see from your screenshot, you can configure levels 1-9 (in JS code, 0-8). These map to the style.listTemplate.listLevels property.

In our Script Lab add-in, we have several samples for working with lists and styles. The following is an excerpt of output from the Get list styles Script Lab sample, when you "Get properties" of a built-in list style. Consider copying an existing list style that has most of what you need then refining it.

Properties of the '1 / 1.1 / 1.1.1' style:

{
    "baseStyle": "No List",
    "builtIn": true,
    "inUse": true,
    "linked": false,
    "nameLocal": "1 / 1.1 / 1.1.1",
    "nextParagraphStyle": "1 / 1.1 / 1.1.1",
    "priority": 100,
    "quickStyle": false,
    "type": "List",
    "unhideWhenUsed": true,
    "visibility": false,
    "listTemplate": {
        "outlineNumbered": true,
        "listLevels": [
            {
                "alignment": "Left",
                "linkedStyle": null,
                "numberFormat": "%1.",
                "numberPosition": 0,
                "numberStyle": "Arabic",
                "resetOnHigher": 0,
                "startAt": 1,
                "tabPosition": 499999.9375,
                "textPosition": 18,
                "trailingCharacter": "TrailingTab"
            },
            {
                "alignment": "Left",
                "linkedStyle": null,
                "numberFormat": "%1.%2.",
                "numberPosition": 18,
                "numberStyle": "Arabic",
                "resetOnHigher": 1,
                "startAt": 1,
                "tabPosition": 499999.9375,
                "textPosition": 39.5999984741211,
                "trailingCharacter": "TrailingTab"
            },
            {
                "alignment": "Left",
                "linkedStyle": null,
                "numberFormat": "%1.%2.%3.",
                "numberPosition": 36,
                "numberStyle": "Arabic",
                "resetOnHigher": 2,
                "startAt": 1,
                "tabPosition": 499999.9375,
                "textPosition": 61.2000007629395,
                "trailingCharacter": "TrailingTab"
            },
            {
                "alignment": "Left",
                "linkedStyle": null,
                "numberFormat": "%1.%2.%3.%4.",
                "numberPosition": 54,
                "numberStyle": "Arabic",
                "resetOnHigher": 3,
                "startAt": 1,
                "tabPosition": 499999.9375,
                "textPosition": 86.4000015258789,
                "trailingCharacter": "TrailingTab"
            },
            {
                "alignment": "Left",
                "linkedStyle": null,
                "numberFormat": "%1.%2.%3.%4.%5.",
                "numberPosition": 72,
                "numberStyle": "Arabic",
                "resetOnHigher": 4,
                "startAt": 1,
                "tabPosition": 499999.9375,
                "textPosition": 111.599998474121,
                "trailingCharacter": "TrailingTab"
            },
            {
                "alignment": "Left",
                "linkedStyle": null,
                "numberFormat": "%1.%2.%3.%4.%5.%6.",
                "numberPosition": 90,
                "numberStyle": "Arabic",
                "resetOnHigher": 5,
                "startAt": 1,
                "tabPosition": 499999.9375,
                "textPosition": 136.800003051758,
                "trailingCharacter": "TrailingTab"
            },
            {
                "alignment": "Left",
                "linkedStyle": null,
                "numberFormat": "%1.%2.%3.%4.%5.%6.%7.",
                "numberPosition": 108,
                "numberStyle": "Arabic",
                "resetOnHigher": 6,
                "startAt": 1,
                "tabPosition": 499999.9375,
                "textPosition": 162,
                "trailingCharacter": "TrailingTab"
            },
            {
                "alignment": "Left",
                "linkedStyle": null,
                "numberFormat": "%1.%2.%3.%4.%5.%6.%7.%8.",
                "numberPosition": 126,
                "numberStyle": "Arabic",
                "resetOnHigher": 7,
                "startAt": 1,
                "tabPosition": 499999.9375,
                "textPosition": 187.199996948242,
                "trailingCharacter": "TrailingTab"
            },
            {
                "alignment": "Left",
                "linkedStyle": null,
                "numberFormat": "%1.%2.%3.%4.%5.%6.%7.%8.%9.",
                "numberPosition": 144,
                "numberStyle": "Arabic",
                "resetOnHigher": 8,
                "startAt": 1,
                "tabPosition": 499999.9375,
                "textPosition": 216,
                "trailingCharacter": "TrailingTab"
            }
        ]
    }
}

List levels of the '1 / 1.1 / 1.1.1' style:

{
    "items": [
        {
            "alignment": "Left",
            "linkedStyle": null,
            "numberFormat": "%1.",
            "numberPosition": 0,
            "numberStyle": "Arabic",
            "resetOnHigher": 0,
            "startAt": 1,
            "tabPosition": 499999.9375,
            "textPosition": 18,
            "trailingCharacter": "TrailingTab"
        },
        {
            "alignment": "Left",
            "linkedStyle": null,
            "numberFormat": "%1.%2.",
            "numberPosition": 18,
            "numberStyle": "Arabic",
            "resetOnHigher": 1,
            "startAt": 1,
            "tabPosition": 499999.9375,
            "textPosition": 39.5999984741211,
            "trailingCharacter": "TrailingTab"
        },
        {
            "alignment": "Left",
            "linkedStyle": null,
            "numberFormat": "%1.%2.%3.",
            "numberPosition": 36,
            "numberStyle": "Arabic",
            "resetOnHigher": 2,
            "startAt": 1,
            "tabPosition": 499999.9375,
            "textPosition": 61.2000007629395,
            "trailingCharacter": "TrailingTab"
        },
        {
            "alignment": "Left",
            "linkedStyle": null,
            "numberFormat": "%1.%2.%3.%4.",
            "numberPosition": 54,
            "numberStyle": "Arabic",
            "resetOnHigher": 3,
            "startAt": 1,
            "tabPosition": 499999.9375,
            "textPosition": 86.4000015258789,
            "trailingCharacter": "TrailingTab"
        },
        {
            "alignment": "Left",
            "linkedStyle": null,
            "numberFormat": "%1.%2.%3.%4.%5.",
            "numberPosition": 72,
            "numberStyle": "Arabic",
            "resetOnHigher": 4,
            "startAt": 1,
            "tabPosition": 499999.9375,
            "textPosition": 111.599998474121,
            "trailingCharacter": "TrailingTab"
        },
        {
            "alignment": "Left",
            "linkedStyle": null,
            "numberFormat": "%1.%2.%3.%4.%5.%6.",
            "numberPosition": 90,
            "numberStyle": "Arabic",
            "resetOnHigher": 5,
            "startAt": 1,
            "tabPosition": 499999.9375,
            "textPosition": 136.800003051758,
            "trailingCharacter": "TrailingTab"
        },
        {
            "alignment": "Left",
            "linkedStyle": null,
            "numberFormat": "%1.%2.%3.%4.%5.%6.%7.",
            "numberPosition": 108,
            "numberStyle": "Arabic",
            "resetOnHigher": 6,
            "startAt": 1,
            "tabPosition": 499999.9375,
            "textPosition": 162,
            "trailingCharacter": "TrailingTab"
        },
        {
            "alignment": "Left",
            "linkedStyle": null,
            "numberFormat": "%1.%2.%3.%4.%5.%6.%7.%8.",
            "numberPosition": 126,
            "numberStyle": "Arabic",
            "resetOnHigher": 7,
            "startAt": 1,
            "tabPosition": 499999.9375,
            "textPosition": 187.199996948242,
            "trailingCharacter": "TrailingTab"
        },
        {
            "alignment": "Left",
            "linkedStyle": null,
            "numberFormat": "%1.%2.%3.%4.%5.%6.%7.%8.%9.",
            "numberPosition": 144,
            "numberStyle": "Arabic",
            "resetOnHigher": 8,
            "startAt": 1,
            "tabPosition": 499999.9375,
            "textPosition": 216,
            "trailingCharacter": "TrailingTab"
        }
    ]
}
zeratul1215 commented 1 month ago

thank you so much, I will try these on the weekend and update if there are any other problems

zeratul1215 commented 1 week ago

image hi, I want to ask about this

ElizabethSamuel-MSFT commented 1 week ago

To your question about linking each level of your list style's listTemplate.listLevels to a specific style, you should be able to use ListLevel.linkedStyle.

zeratul1215 commented 1 week ago

but how can I add a new self-defined list template to the current word document?

ElizabethSamuel-MSFT commented 1 week ago

The manage-styles snippet shows how to add a new custom style (see the addStyle function). The snippet creates a Paragraph style but in your code, set the styleType param to StyleType.list when you call document.addStyle. Then your custom style will have the listTemplate property available for you to configure.

zeratul1215 commented 1 week ago

thank you, I will try it, and let you know if this works for me

zeratul1215 commented 1 week ago

when I used the code in the example and try to get the items in the listLevel object, it gives me a undefined result image image

ElizabethSamuel-MSFT commented 1 week ago

@zeratul1215 Can you share your code sample or a GitHub gist? Thx.

zeratul1215 commented 1 week ago

sure `import React, { useState } from "react";

const NumberedListTest = () => {

const addAlistStyle = async () => {
    try {
        await Word.run(async (context) => {
            const newStyleName = "testListStyle";
            const styleCollection = context.document.getStyles();
            const style = styleCollection.getByNameOrNullObject(newStyleName);
            style.load();
            await context.sync();
            if (!style.isNullObject) {
                return;
            } else {
                const style = context.document.addStyle(newStyleName, Word.StyleType.list);
                style.load();
                await context.sync();
                console.log(`${newStyleName} has been added to the style list.`);
            }
        })
    } catch (error) {
        console.error(error);
    }
}

const getListTemplate = async () => {
    try {
        await Word.run(async (context) => {
            const styleName = "testListStyle";
            const style = context.document.getStyles().getByNameOrNullObject(styleName);
            style.load("type");
            await context.sync();

            if (style.isNullObject || style.type != Word.StyleType.list) {
                console.log("style not found");
                return;
            } else {
                style.load();
                style.listTemplate.load();
                await context.sync();
                console.log(`Properties of the '${styleName}' style:`, style);

                const listLevels = style.listTemplate.listLevels;
                listLevels.load("items");
                await context.sync();
                console.log(`List levels of the '${styleName}' style:`, listLevels);

            }
        })
    } catch (error) {
        console.error(error);
    }
}

return (
    <div>
        <h1>Numbered List Test</h1>
        <button className= "bg-red-500 text-white px-4 py-2 rounded-md" onClick={addAlistStyle}>add a list style</button>
        <button className= "bg-red-500 text-white px-4 py-2 rounded-md" onClick={getListTemplate}>get list levels</button>
    </div>
);

}

export default NumberedListTest;` here are my code

zeratul1215 commented 1 week ago

I noticed that if I create a list style through word ui, then I run this code, I can get Items in the listlevels,

ElizabethSamuel-MSFT commented 1 week ago

@zeratul1215 Thanks for that update. I'll check with the feature crew about this.

In the meantime, are you able to configure the UI-created list style using the API?

Then you might be able to get the JSON version of the final style for import.

zeratul1215 commented 1 week ago

I will try to configure the UI-created list style, but I actually want to do all the "create style" in the add-in. the only way I know to add a style through API is document.addstyle, if I but this function only takes two parameters style name and style type.

zeratul1215 commented 1 week ago

yes, I can configure the UI-created list style, so now the only problem is: is there any way I can create a list style through api and get the items successfully?

ElizabethSamuel-MSFT commented 1 week ago

@zeratul1215 I've confirmed with the API crew that this is a product bug and they're currently working on the fix. I'll transfer this issue to the product repo for them to track to issue there.

zeratul1215 commented 1 week ago

thank you so much for updating, please inform me in this issue once they have fixed the issue

qinliuMSFT commented 1 week ago

@zeratul1215 , we created one internal bug #9439630 for tracking, team is working on the fix, will reply to you as soon as there is any progress.

zeratul1215 commented 1 day ago

is there any update on this bug?