# getOoxml and insertOoxml

Read and write the document as Word for the web does, flat OPC packages with tracked changes and comments in their parts.

`getOoxml` on the body, a paragraph or a range returns the flat-OPC `pkg:package` Word for the web returns. Tracked changes are `w:ins` and `w:del`, and comments sit in their parts. `insertOoxml` places such a package into the document at any location. Anything but a flat `pkg:package` throws `GeneralException`.

```js
await Word.run(async context => {
  context.document.changeTrackingMode = Word.ChangeTrackingMode.trackAll;
  context.document.body.paragraphs.getFirst().insertText(' now', 'End');
  await context.sync();
  const ooxml = context.document.body.getOoxml();
  await context.sync();
  // ooxml.value.includes('<w:ins ') -> true
});
```

How a `Replace` over a range across paragraph marks joins, tracks or refuses is on [insertOoxml Replace across paragraphs](https://www.rystic.ai/docs/simulators/word/features/ooxml-replace.md).

### `getOoxml` leaves out the last paragraph's properties

Every package writes its last paragraph without its paragraph properties: its alignment, style, numbering and mark formatting. The paragraph keeps them.

| Package | Leaves out the properties of |
|---|---|
| the body's | the document's last paragraph |
| a range's | the paragraph the range ends in |
| a paragraph's own | that paragraph: it writes none |

Once a paragraph follows it, the body's package writes them. `office.docx()` keeps every paragraph's.

### `getOoxml` writes a content control around table rows as it was imported

Text your add-in edits inside such a control, such as a repeating section's rows, reads back in `paragraphs`, `search` and `getTrackedChanges`. But the body's `getOoxml` writes those rows as the seed had them, or as the last `insertOoxml` left them. So replacing the body with its own `getOoxml` loses those edits, in Word and in the simulator.

`getOoxml` of a paragraph there, or of a range inside one, writes that paragraph's imported copy at the same offsets, formatting changes left out. These throw `GeneralException`:

- a paragraph whose text runs past its copy, as after your add-in appends to it;
- a range with an end past its copy;
- a paragraph inserted there, which has no copy.

### An `insertOoxml` puts a row control back as `getOoxml` writes it

An `insertOoxml` anywhere in the document first gives each content control around table rows the rows its `getOoxml` writes. That holds through the body, a paragraph or a range, at any location. What your add-in changed inside such a control since goes:

- text inserted, deleted or replaced;
- a paragraph emptied or inserted;
- tracked edits, which leave `getTrackedChanges`.

The `insertOoxml`'s own edit stays, inside such a control too, and the body's `getOoxml` writes it there from then on.

Into a paragraph there, the package lands at the same offsets in the text `getOoxml` writes. Say you insert `X ` at the start of `Second line`. An `insertOoxml` over `line` then ends past that text: it throws `GeneralException` and leaves the document as it was. `insertText`, the body's `insertParagraph` and `delete` leave the control as edited.

### Drawings

The simulator keeps a text box or shape as the document wrote it, ids and VML fallback included.

**Differs from Word for the web:** Word gives a text box or shape random ids when it opens a document, and renders its VML fallback afresh. So `getOoxml` of a drawing differs.

### Carriage returns

The simulator's `getOoxml` of a paragraph holding a carriage return (`w:cr`) holds the paragraph's last character.

**Differs from Word for the web:** Word's `getOoxml` of such a paragraph leaves out its last character.

---

Source: https://www.rystic.ai/docs/simulators/word/features/ooxml · Markdown: https://www.rystic.ai/docs/simulators/word/features/ooxml.md
