Search code examples
reactjscsv

Can I display texted formatted as html in CSV Downloader


I have reports that users can download into a .csv file but a few of the fields have HTML formatting from a WYSIWYG editor. Is there a way to display the HTML in the field in the .csv field?

Here is my ExportReport.jsx file:

import CsvDownloader from "react-csv-downloader";
import moment from "moment";

const ExportReport = ({ reports }) => {
  let columns = [];
  let datas = [];

  if (reports) {
    columns = [
      {
        id: "matchType",
        displayName: "Match Type",
      },
      {
        id: "eventName",
        displayName: "Event Name",
      },
      {
        id: "matchDate",
        displayName: "Match Date",
      },
      {
        id: "opponentName",
        displayName: "Opponent Name",
      },
      {
        id: "weightCategory",
        displayName: "Weight Category",
      },
      {
        id: "club",
        displayName: "Club",
      },
      {
        id: "country",
        displayName: "Country",
      },
      {
        id: "rank",
        displayName: "Rank",
      },
      {
        id: "grip",
        displayName: "Grip",
      },
      {
        id: "opponentAttacks",
        displayName: "Opponent Attacks",
      },
      {
        id: "attackNotes",
        displayName: "Opponent Attack Notes",
      },
      {
        id: "myAttacks",
        displayName: "My Attacks",
      },
      {
        id: "My Attack Notes",
        displayName: "My Attack Notes",
      },
      {
        id: "result",
        displayName: "Result",
      },
      {
        id: "score",
        displayName: "score",
      },
      {
        id: "videoURL",
        displayName: "Video URL",
      },
    ];

    let opponentAttacks = "";
    let athleteAttacks = "";

    reports.map((report) => {
      report.opponentAttacks.map((attack) => {
        opponentAttacks += attack + " ";
      });
      report.athleteAttacks.map((attack) => {
        athleteAttacks += attack + " ";
      });
      datas.push({
        matchType: report.matchType,
        eventName: report.eventName,
        matchDate: moment(report.matchDate).format("MM/DD/YYYY"),
        //endtDate: report.eventEndDate,
        opponentName: report.opponentName,
        weightCategory: report.weightCategory,
        club: report.club,
        country: report.country,
        rank: report.rank,
        grip: report.grip,
        opponentAttacks: opponentAttacks,
        attackNotes: report.opponentAttackNotes,
        myAttacks: athleteAttacks,
        myAttachNotes: report.athleteAttackNotes,
        result: report.result,
        scor: report.scor,
        videoURL: report.videoURL,
      });
    });
  }
  return (
    <CsvDownloader
      filename="matchReport"
      extension=".csv"
      separator=","
      //wrapColumnChar="'"
      columns={columns}
      datas={datas}
      text="Download Reports"
      className="profile_btn"
    />
  );
};

export default ExportReport;

The report.athleteAttackNotes and report.opponentAttackNotes have html formatting and I would like that to display as formatted in the .csv file if possible.

In a test report for the report.opponentAttacks I have I have a test one in the .csv file that is:

<p>Rocky's attack notes</p><p><br></p><p><strong>Some Bold</strong></p>

and if at all possible I would like this text to be displayed with the spacing the <p></p> and <br> tags would provide in an HTML file.

I'm also not tied to a .csv file. That was just the only solution I found to download the reports. If there is some other way please let me know.


Solution

  • As suggested in the comments, thanks @tripleee. My issue was that I was trying to display html in .csv which by definition is plain text, so I found another solution to download into Excel which keeps my formatting.

    So I created a button on the page I was previously downloading the .csv from. Then I created a table with all the data and added a button to export to excel.

    I need to format it a bit, but here is the ReportsTable.jsx file:

    const ReportsTable = ({ reports }) => {
      const exportTableToExcel = () => {
        // Get the table HTML
        const table = document.getElementById("my-table");
        if (!table) return;
    
        const tableHTML = table.outerHTML.replace(/ /g, "%20");
    
        // Specify the data type
        const dataType = "application/vnd.ms-excel";
    
        // Define the file name
        const fileName = "table.xls";
    
        // Create a download link element
        const downloadLink = document.createElement("a");
    
        // Browser check to support Microsoft Excel file download
        if (navigator.msSaveOrOpenBlob) {
          const blob = new Blob(["\ufeff", tableHTML], {
            type: dataType,
          });
          navigator.msSaveOrOpenBlob(blob, fileName);
        } else {
          // Create a link to the file
          downloadLink.href = `data:${dataType}, ${tableHTML}`;
    
          // Setting the file name
          downloadLink.download = fileName;
    
          // Triggering the function
          downloadLink.click();
        }
      };
    
      return (
        <div>
          <table id="my-table">
            <thead>
              <tr>
                <th>Match Type</th>
                <th>Event Name</th>
                <th>Match Date</th>
                <th>Opponent Name</th>
                <th>Weight Category</th>
                <th>Club</th>
                <th>Country</th>
                <th>Rank</th>
                <th>Grip</th>
                <th>Opponent Attacks</th>
                <th>Opponent Attack Notes</th>
                <th>My Attacks</th>
                <th>My Attack Notes</th>
                <th>Result</th>
                <th>Score</th>
                <th>Video URL</th>
              </tr>
            </thead>
            <tbody>
              {reports &&
                reports.map((report) => (
                  <tr>
                    <td>{report.matchType}</td>
                    <td>{report.eventName}</td>
                    <td>{moment(report.matchDate).format("MM/DD/YYYY")}</td>
                    <td>{report.opponentName}</td>
                    <td>{report.weightCategory}</td>
                    <td>{report.club}</td>
                    <td>{report.country}</td>
                    <td>{report.rank}</td>
                    <td>{report.grip}</td>
                    <td>{report.opponentAttacks}</td>
                    <td>
                      <div
                        dangerouslySetInnerHTML={{
                          __html: `${report.opponentAttackNotes}`,
                        }}
                      />
                    </td>
                    <td>{report.athleteAttacks}</td>
                    <td>
                      <div
                        dangerouslySetInnerHTML={{
                          __html: `${report.athleteAttackNotes}`,
                        }}
                      />
                    </td>
                    <td>{report.result}</td>
                    <td>{report.scor}</td>
                    <td>{report.videoURL}</td>
                  </tr>
                ))}
            </tbody>
          </table>
          <button onClick={exportTableToExcel}>Export to Excel</button>
        </div>
      );
    };
    
    export default ReportsTable;