Open existing Word document in office js - ms-word

I'm new in office js and I want to know if is possible to open an existing document in Word add-in. I've already tried get my file as base64 but didn't work ->
function dataURLtoFile() {
Word.run(async (context) => {
var body = context.document.body;
body.insertFileFromBase64(getBase64(), Word.InsertLocation.start);
await context.sync();
console.log('Added base64 encoded text to the beginning of the document body.');
});
}

Related

How to extract Header and Footer section from openXML file?

I have Open Xml file which has Header, Body and Footer content. When I am trying to insert that open Xml it always picking only Body related part and not able to extract Header & Footer section data out of it.
I tried below snippet, but it always printing Body part data instead of Header data which resides in Header1.xml
ps: WORD_OPEN_XML is holding whole content
async function insertHeader() {
Word.run(async (context) => {
const mySections = context.document.sections;
context.load(mySections);
await context.sync();
for (let i = 0; i < mySections.items.length; i++) {
mySections.items[i].getHeader('Primary').insertOoxml(WORD_OPEN_XML, 'Replace');
}
await context.sync();
});
}
Please help me to insert Header and Footer part from that open Xml
WORD_OPEN_XML

Replace text of current paragraph in MS word Office.js add-in

In a Word add-in, I'm trying to:
receive documentSelectionChanged events,
get the text of the current paragraph, and
replace the string foo with the string bar in the current paragraph.
Everything is working except the last part. The text of the Word document isn't changing.
This is my code:
function updateText() {
var range, foo_range, par;
Word.run(function (context) {
range = context.document.getSelection();
range.paragraphs.load('items');
return context.sync()
.then(function() {
par = range.paragraphs.items[0];
console.log(par.text); // THIS WORKS!
foo_range = par.search('foo');
foo_range.load('items');
})
.then(context.sync)
.then(function() {
console.log(foo_range.items[0].text); // THIS WORKS!
foo_range.items[0].insertText('bar', 'Replace');
// Here, I am trying all the load options I can think of
foo_range.load('items');
foo_range.items[0].load('text');
foo_range.load('text');
range.paragraphs.load('items');
range.paragraphs.load('text');
return context.sync();
});
});
}
Any idea why foo doesn't get replaced by bar in the Word document?
I can't reproduce. Your code works for me on desktop Office 365.
BTW, none of those load calls before the last context.sync do anything, and you should delete them. You only need to load a property (and then sync) when you are going to read the property after the sync. Since you are only writing to the document, you don't need to load anything.

Express [413 too large] with QuillJS image

I am trying to use QuillJS to let the user write a rich text, and then store it as JSON to display later on. There are 2 of these rich text areas in a single form, and may include images. QuillJS encodes images as base64 strings, and my POST request results in 413 by Express.
I have tried to change the limits by adding express json parameters, even trying extreme numbers.
// app.js
//----------------------------------------------------
// Middlewares
//----------------------------------------------------
app.use(express.json({limit: '2000mb'}));
app.use(express.urlencoded({extended: true, limit:'2000mb'}));
Even this did not help and I think it is not logical to let these parameters with such values.
I tried with json and urlencoded enctypes. When I tried to post with multipart/form, req.body was empty.
// My html page (pugJS)
form(enctype='application/x-www-form-urlencoded', action='/editor/page',
method='POST', onsubmit='return addContent()')
.form-control
label Content-1
div#toolbar
div#editor
input#content(name='content', type='text', hidden)
addContent() function that runs before form submit simply changes input#content's value with JSON.stringify(#editor.getContents())
I want to be able to store two quill content in a single database row, to display later.
A better approach to this would be to overwrite the image upload function and then save the image in Amazon S3 or some cloud server. Then you paste it inside the editor as <img src="http://uploaded-image-url"> This would solve your problem of maximum memory issue.
I fixed my problem few hours before #argo mentioned and I did it that way. So I wanted to post little bit of detail to the solution. I have been also guided by a github issue but can't seem to find the link again, in case I find it I will edit the post and add it.
// Quill - EN content
var quillEn = new Quill('#editor-en', {
modules: {
toolbar: toolbarOptions
},
theme: 'snow'
});
// set custom image handler
quillEn.getModule('toolbar').addHandler('image', () => {
selectLocalImage(quillEn);
});
// create fake input to upload image to quill
function selectLocalImage(editor) {
const input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/png, image/jpeg')
input.click();
// Listen upload local image and save to server
input.onchange = () => {
const file = input.files[0];
saveImageToServer(editor, file);
};
}
// upload image to server
function saveImageToServer(editor, file) {
const fd = new FormData();
fd.append('image', file);
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/page/upload_image', true);
xhr.onload = () => {
if (xhr.status === 200) {
// this is callback data: url
const url = JSON.parse(xhr.responseText).data;
insertToEditor(editor, url);
}
};
xhr.send(fd);
}
// manipulate quill to replace b64 image with uploaded image
function insertToEditor(editor, url) {
// push image url to rich editor.
const range = editor.getSelection();
editor.insertEmbed(range.index, 'image', url.toString());
}
In the backend where you POST image, you must return json as { data: FullUrlToImg } with 200 response, if you want to change your status to 201 or something else, don't forget to update it in saveImageToServer function.
So to summarize, you set custom image handler for your quill editor, you post the image to server as soon as user chooses to insert, then you replace the URL with your uploaded image in the editor.
Thanks.

Implementing a "Save As" using the vscode API

I've been trying to figure out the best way to implement a "Save As" using the vscode extension API.
So far, here's the best I've got:
// First turn the path we were given into an absolute path
// Relative paths are interpreted as relative to the original file
const newFileAbsolutePath = path.isAbsolute(saveFileDetails.newPath) ?
saveFileDetails.newPath :
path.resolve(path.dirname(saveFileDetails.filePath), saveFileDetails.newPath);
// Create an "untitled-scheme" path so that VSCode will let us create a new file with a given path
const newFileUri = vscode.Uri.parse("untitled:" + newFileAbsolutePath);
// Now we need to copy the content of the current file,
// then create a new file at the given path, insert the content,
// save it and open the document
return vscode.workspace.openTextDocument(saveFileDetails.filePath)
.then((oldDoc) => {
return vscode.workspace.openTextDocument(newFileUri)
.then((newDoc) => {
return vscode.window.showTextDocument(newDoc, 1, false)
.then((editor) => {
return editor.edit((editBuilder) => {
editBuilder.insert(new vscode.Position(0, 0), oldDoc.getText());
})
.then(() => {
return newDoc.save()
.then(() => EditorOperationResponse.Completed);
});
});
});
});
We open the old doc, then open a new doc (which is an untitled document), then insert the old doc's text into the new doc and then save the new doc.
The new doc then closes (for some reason).
Anyone have any advice?
It seems like this is a known issue and caused by the use of the untitled:// scheme:
TextDocument.save() closes untitled documents (#29156)
For now, you could work around it by just reopening the file again since you know the final URI (unlike in the case of the person who reported the issue).
newDoc.save().then((completed) => {
const finalUri = vscode.Uri.file(newFileAbsolutePath);
vscode.workspace.openTextDocument(finalUri).then((doc) => {
vscode.window.showTextDocument(doc, {preview: false});
})
});
Unfortunatenly this does lead to a noticable "flicker"-effect. To avoid this, I'd suggest to simply bypass the VSCode API and use fs for file IO, and only use vscode for showing the file at the end. This also simplifies the code quite a bit:
import * as fs from 'fs';
function runCommand() {
// obtain newFileAbsolutePath / oldFileAbsolutePath
var oldDocText = fs.readFileSync(oldFileAbsolutePath);
fs.writeFileSync(newFileAbsolutePath, oldDocText);
const finalUri = vscode.Uri.file(newFileAbsolutePath);
vscode.workspace.openTextDocument(finalUri).then((doc) => {
vscode.window.showTextDocument(doc, {preview: false});
});
}

How I can remove all hyperlinks in Word document using office.js?

I need to remove all hyperlinks in Word document.
How I can do it?
Firstly, we need to select all document body. As a result, we have the range of selection. We should to set hyperlink for this range as undefined.
Word.run(function (context) {
var body = context.document.body;
var range = body.getRange();
range.hyperlink = undefined;
return context.sync();;
});