Hi Dmitrii,
We are using the spreadsheet editor version 8.2.2.22.
This is the code responsible for converting our value from the richt text editor we use to html for pasting with pasteHtml.
// export const LINE_BREAK = '
'
// export const LINE_BREAK = '\u2028'
export const LINE_BREAK = '<br>'
const convertTipTapToOnlyOfficeHtml = (tiptapHtml: string): string => {
if (!tiptapHtml) return ''
// Create a DOM parser to parse the HTML string
const parser = new DOMParser()
const doc = parser.parseFromString(tiptapHtml, 'text/html')
// Process the document
const processedHtml = processNode(doc.body)
return processedHtml
}
const processNode = (node: Node): string => {
let result = ''
// Process each child node
node.childNodes.forEach((child) => {
if (child.nodeType === Node.TEXT_NODE) {
// Text node - add its content
result += child.textContent
} else if (child.nodeType === Node.ELEMENT_NODE) {
const element = child as HTMLElement
const tagName = element.tagName.toLowerCase()
if (tagName === 'ul') {
// Process unordered list
element.querySelectorAll('li').forEach((li) => {
result += `• ${li.textContent}${LINE_BREAK}`
})
} else if (tagName === 'ol') {
// Process ordered list
element.querySelectorAll('li').forEach((li, index) => {
result += `${index + 1}. ${li.textContent}${LINE_BREAK}`
})
} else if (tagName === 'p') {
// Process paragraph - extract content without the p tags
if (element.textContent?.trim()) {
// Check if paragraph contains <br> tags
if (
element.innerHTML.includes('<br>') ||
element.innerHTML.includes('<br/>') ||
element.innerHTML.includes('<br />')
) {
// Handle paragraphs with <br> tags - split by <br> and process each line
const lines = element.innerHTML.split(/<br\s*\/?>/i)
lines.forEach((line, index) => {
// Create a temporary element to parse the line
const tempDiv = document.createElement('div')
tempDiv.innerHTML = line
result += processNode(tempDiv)
// Add line break after each line except the last one
if (index < lines.length - 1) {
result += LINE_BREAK
}
})
} else {
// Regular paragraph - process normally
result += processNode(element)
}
// Add line break after paragraph if it's not the last element
if (element.nextElementSibling) {
result += LINE_BREAK
}
} else {
// Empty paragraph - add line break
result += LINE_BREAK
}
} else if (tagName === 'br') {
// Process <br> tags as line breaks
result += LINE_BREAK
} else if (tagName === 'table') {
// Process table
const rows = element.querySelectorAll('tr')
rows.forEach((row, rowIndex) => {
const cells = row.querySelectorAll('th, td')
const rowContent = Array.from(cells)
.map((cell) => cell.textContent?.trim() || '')
.join(' | ')
result += rowContent
// Add line break after each row
if (rowIndex < rows.length - 1) {
result += LINE_BREAK
}
})
// Add line break after the table
if (element.nextElementSibling) {
result += LINE_BREAK
}
} else if (tagName === 'img') {
// Process image - preserve the image tag with its attributes
const img = element as HTMLImageElement
const src = img.getAttribute('src') || ''
result += `<img src="${src}">`
} else if (['strong', 'b', 'em', 'i', 'u', 'span'].includes(tagName)) {
// Preserve formatting tags
result += `<${tagName}>${processNode(element)}</${tagName}>`
} else if (!['tr', 'th', 'td'].includes(tagName)) {
// Process other elements recursively (skip table cells as they're handled by the table processor)
result += processNode(element)
}
}
})
return result
}
console.log('value', value)
const html = convertTipTapToOnlyOfficeHtml(value)
console.log('html', html)
// @ts-ignore
window.connector.executeMethod('PasteHtml', [html])
Example input value before calling convertTipTapToOnlyOfficeHtml:
<p><strong>SEQUESTO BV</strong></p><p></p><p><em>Emiel Fleerackerslaan(MEL) 25</em><br><br><u>9120 Beveren-Kruibeke-Zwijndrecht</u></p>
Example html for ‘PasteHtml’:
<strong>SEQUESTO BV</strong><br><br><em>Emiel Fleerackerslaan(MEL) 25</em><br><br><u>9120 Beveren-Kruibeke-Zwijndrecht</u>
We expect that when pasting html with a
we would get a line break inside the same cell, however this makes it jump to a new cell. What we really want is af you would manually do alt + enter inside a cell, but this doesn’t work with
.
If we use the unicode character above in the code it will work fine visually in the spreadsheet editor, however on download of the file and opening it on your desktop the line breaks will be gone and this is probably because the unicode is not really picked up by excel and excel expects a \n instead.
When we do alt + enter in a cell I can see that it is represented by a \n by only office, but how can we paste html and have a proper \n in there which works visually on the spreadsheet editor, but also after downloading?
It is really not hard to reproduce, just paste html with the ‘PasteHtml’ method including a
html element, which should create a line break inside the cell and not move to a new cell.
test.xlsx (6.2 KB)
Kind regards,
Joachim