react-pdf-html icon indicating copy to clipboard operation
react-pdf-html copied to clipboard

"colspan" doesn't seem to be working

Open pedlima opened this issue 3 years ago • 4 comments

Unfortunately, I'm trying to have "colspan" working but it never recognizes. It's just as if it was nothing there. Also, if I associate a class in a "tr" or "td", it also does nothing as it simply ignores it as well.

Have anyone else came across thys problem?

pedlima avatar Apr 05 '22 12:04 pedlima

Any solution for this?

pedlima avatar Oct 19 '22 15:10 pedlima

I have implemented custom renderer for rendercell. I have handle colspan along with col resize based on my requirement. Please check if this can help you. let me know if this could solve your problem. @pedlima @danomatic

renderCell(data) {
        const { style, element, children } = data
        const table = element.closest('table');
        if (!table) {
            throw new Error('td element rendered outside of a table');
        }
        const tableStyles = table.style.reduce(
            (combined, tableStyle) => Object.assign(combined, tableStyle),
            {}
        );
        const baseStyles = {
            border: tableStyles.border,
            borderColor: tableStyles.borderColor,
            borderWidth: tableStyles.borderWidth,
            borderStyle: tableStyles.borderStyle,
        };
        if (
            (tableStyles).borderSpacing &&
            (tableStyles).borderCollapse !== 'collapse'
        ) {
            baseStyles.width = tableStyles.borderWidth;
            baseStyles.margin = (tableStyles).borderSpacing;
        } else {
            baseStyles.borderRightWidth = 0;
            baseStyles.borderBottomWidth = 0;
            if (element.indexOfType !== 0) {
                baseStyles.borderLeftWidth = tableStyles.borderWidth;
                baseStyles.borderTopWidth = tableStyles.borderWidth;
            }
        }
        const overrides = {};
        const tableElement = findUpTagInParentNodes(element, 'TABLE');
        const elementNodes = tableElement.childNodes.filter(ele=>ele.nodeType === 1);
        let colElements = [];
        for(let i = 0; i < elementNodes.length; i++){
            if(elementNodes[i].tagName === 'COLGROUP'){
                colElements =  elementNodes[i].childNodes.filter(ele=>ele.nodeType === 1);
            }
        }
        //column resize handling
        if(colElements?.length){
            let colElement = colElements.find(o => o.indexOfType === element.indexOfType);
            overrides.flexBasis = colElement?.style[0]['width'];
            overrides.flexGrow = 0;
            overrides.flexShrink = 0;
        }

        //colspan handling
        if (element.attributes && element.attributes.colspan) {
            let colspan = parseInt(element.attributes.colspan, 10);
            if (!isNaN(colspan)) {
                let colSpanWidth = 0;
                let startIndex = element.indexOfType;
                while (colspan>0 && colElements.length) {
                    let obj = colElements.find(o => o.indexOfType === startIndex);
                    if(obj){
                        colSpanWidth = colSpanWidth + parseInt(obj.style[0]['width'],10)
                    }
                    startIndex++;
                    colspan--;
                }
                overrides.flexBasis = colSpanWidth ? colSpanWidth + '%': colspan;
                overrides.flexGrow = 0;
                overrides.flexShrink = 0;
            }
        }
        return <View style={[baseStyles, ...style, overrides]}>{children}</View>;
    }

//set your custom renderers

const customRenderes = {
            'td': this.renderCell.bind(this),
            'th': this.renderCell.bind(this),
      }

//pass here

 <Html  renderers={customRenderes}>
             //your html
  </Html>

shai93 avatar Oct 20 '22 10:10 shai93

Oh, awesome!

Thank you so much for your quick answer and kind help.

I will check this later on and I will let you know. :)

pedlima avatar Oct 20 '22 16:10 pedlima

How the support for this going because I modified the code to comply with ckEditor but not getting the result

 const renderCell = (data) => {
    const { style, element, children } = data;
    //console.log(element);
    const table = element.closest('table');
    if (!table) {
      throw new Error('td element rendered outside of a table');
    }
    const tableStyles = table.style.reduce(
      (combined, tableStyle) => Object.assign(combined, tableStyle),
      {}
    );
    const baseStyles = {
      border: tableStyles.border,
      borderColor: tableStyles.borderColor,
      borderWidth: tableStyles.borderWidth,
      borderStyle: tableStyles.borderStyle
    };
    if (tableStyles.borderSpacing && tableStyles.borderCollapse !== 'collapse') {
      baseStyles.width = tableStyles.borderWidth;
      baseStyles.margin = tableStyles.borderSpacing;
    } else {
      baseStyles.borderWidth = 0;
      baseStyles.borderBottomWidth = 0;
      if (element.indexOfType !== 0) {
        baseStyles.borderWidth = tableStyles.borderWidth;
        //baseStyles.borderTopWidth = tableStyles.borderWidth;
      }
    }
    const overrides = {};
    const tableElement = findUpTagInParentNodes(element, 'TABLE' || 'table');
    const elementNodes = tableElement.childNodes.filter((ele) => ele.nodeType === 1);
    let colElements = [];
    let rowElements = [];
    for (let i = 0; i < elementNodes.length; i++) {
      if (elementNodes[i].tagName === 'TBODY') {
        colElements = elementNodes[i].childNodes.filter((ele) => ele.nodeType === 1);
        rowElements = elementNodes[i].childNodes.filter((ele) => ele.nodeType === 1);
      }
    }
    //column resize handling
    if (colElements?.length) {
      let colElement = colElements.find((o) => o.indexOfType === element.indexOfType);
      overrides.flexBasis = colElement?.style[0]['width'];
      overrides.flexGrow = 0;
      overrides.flexShrink = 0;
    }

    if (rowElements?.length) {
      let rowElement = rowElements.find((o) => o.indexOfType === element.indexOfType);
      let rowspan = parseInt(element._rawAttrs.rowSpan, 10);

      //console.log(rowElement, 'rowElement');
      const relativeHeight = rowspan * 100;
      overrides.flexBasis = relativeHeight + '%';
      overrides.flexGrow = 0;
      overrides.flexShrink = 0;
    }

    //colspan handling
    if (element.attributes && element._rawAttrs.colSpan) {
      let colspan = parseInt(element._rawAttrs.colSpan, 10);
      if (!isNaN(colspan)) {
        let colSpanWidth = 0;
        let startIndex = element.indexOfType;
        while (colspan > 0 && colElements.length) {
          let obj = colElements.find((o) => o.indexOfType === startIndex);
          if (obj) {
            colSpanWidth = colSpanWidth + parseInt(obj.style[0]['width'], 10);
          }
          startIndex++;
          colspan--;
        }
        overrides.flexBasis = colSpanWidth ? colSpanWidth + '%' : colspan;
        overrides.flexGrow = 0;
        overrides.flexShrink = 0;
      }
    }
    if (element.attributes && element._rawAttrs.rowSpan) {
      let rowspan = parseInt(element._rawAttrs.rowSpan, 10);
      // Calculate the relative height as a percentage of the normal row height
      const relativeHeight = rowspan * 100;
      if (!isNaN(rowspan)) {
        // Apply the relative height to the cell

        overrides.flexBasis = relativeHeight + '%'; // Use '%' for relative height
        overrides.flexGrow = 0;
        overrides.flexShrink = 0;
        overrides.fontSize = '32px';
      }
    }

    return <View style={[baseStyles, ...style, overrides]}>{children}</View>;
  };

  const customeRender = {
    td: renderCell.bind(this),
    th: renderCell.bind(this)
  };
  

please help if i've done something wrong.

I should mention I edited mostly to handle rowSpan i dont have a colSpan usage for now.

Trev-Chumba avatar Oct 02 '23 11:10 Trev-Chumba