Как преобразовать данные json в формат PDF с помощью typescript

#javascript #angular #pdf #jspdf

#javascript #angular #PDF #jspdf

Вопрос:

у меня есть данные json, мне нужно преобразовать их в формат pdf, нажав кнопку PDF в пользовательском интерфейсе. Я хочу, чтобы формат pdf отображался в этом формате шаблона. Я сделал несколько вещей, но я не понимаю, как привязать ответ к функции pdf. Здесь я хочу, чтобы были сопоставлены 2 сценария, здесь в "actualExpenses" массиве мне нужно отобразить все значения в блоке и иметь "expenses" массив в каждом из массивов объектов «actualExpenses», и я хочу, чтобы этот "expenses" массив объектов находился чуть выше конкретных объектов «actualExpenses».

ДЕМОНСТРАЦИЯ: ДЕМО

Шаблон:

Изображение

TS:

 captureScreen() {
    this.displayTable = true;
    let grossItems = [];
    grossItems.push(this.grossItems);
    console.log(grossItems)
    var doc = new jsPDF();
        var col = [
          "Actual",
          "Based Amount",
          "Fixed %",
          "80% GU ",
          "85% GU",
          "90% GU",
          "95% GU",
          "100% GU"
        ];
        var col1 = [
          "Estimate",
           "Based Amount",
          "Fixed %",
          "80% GU ",
          "85% GU",
          "90% GU",
          "95% GU",
          "100% GU"
        ];
        var rows = [];
        for (let i = 0; i < grossItems[0].actualExpenses.length; i  ) {
          var temp = [];
          for (var key in grossItems[0].actualExpenses[i]) {
            temp.push(grossItems.actualExpenses[i][key]);
          }
          rows.push(temp);
          console.log(temp, "temp");
        }
        doc.setFont("Times New Roman");
        doc.setFontSize(10);
        doc.text(20, 10, grossItems.propertyName);
        doc.text(20, 20, "Property Name Goes Here");
        doc.text(20, 30, "Budgeted Year:");
        doc.setTextColor(0, 0, 0);
        doc.text(20, 40, "Actual Occupancy:");
        doc.autoTable(col, rows, {
          theme: "plain",
          startY: 45,
          margin: {
            top: 45
          },
          drawHeaderRow: (head, data) => {
            data.doc.setLineWidth(0.7);
            data.doc.setDrawColor(0, 0, 0);
            data.doc.line(
              data.cursor.x,
              data.cursor.y,
              data.cursor.x   data.table.width,
              data.cursor.y
            );
            data.doc.line(
              data.cursor.x,
              data.cursor.y   head.height,
              data.cursor.x   data.table.width,
              data.cursor.y   head.height
            );
          }
        });
        doc.autoTable(col1, rows, {
          theme: "plain",
          startY: 100,
          margin: {
            top: 100
          },

          drawHeaderRow: (head, data) => {
            data.doc.setLineWidth(0.7);
            data.doc.setDrawColor(0, 0, 0);

            data.doc.line(
              data.cursor.x,
              data.cursor.y,
              data.cursor.x   data.table.width,
              data.cursor.y
            );

            data.doc.line(
              data.cursor.x,
              data.cursor.y   head.height,
              data.cursor.x   data.table.width,
              data.cursor.y   head.height
            );
          }
        });
        document
          .getElementById("convertToPdf")
          .setAttribute("src", doc.output("datauri"));
 }
  

Может ли кто-нибудь помочь мне привязать значения и сделать мой PDF-файл таким, как в шаблоне, я надеюсь, что макет в порядке, теперь единственная проблема — привязать значения к шаблону.

Ответ №1:

ваш captureScreen() должен выглядеть так.

 captureScreen() {
this.displayTable = true;
let grossItems = [];
grossItems.push(this.grossItems);
console.log(grossItems)
var doc = new jsPDF();
    var col = [
      "Actual",
      "Based Amount",
      "Fixed %",
      "80% GU ",
      "85% GU",
      "90% GU",
      "95% GU",
      "100% GU"
    ];
    var col1 = [
      "Estimate",
       "Based Amount",
      "Fixed %",
      "80% GU ",
      "85% GU",
      "90% GU",
      "95% GU",
      "100% GU"
    ];
    var rows = [];
    for (let i = 0; i < grossItems[0].actualExpenses.length; i  ) {
      var temp = [];
      temp.push(grossItems[0].actualExpenses[i].category); // ADDED
      for (var key in grossItems[0].actualExpenses[i]) {
        temp.push(grossItems[0].actualExpenses[i].baseAmount); // CHANGED HERE
      }
      rows.push(temp);
      console.log(temp, "temp");
    }
    doc.setFont("Times New Roman");
    doc.setFontSize(10);
    doc.text(20, 10, grossItems[0].propertyName);
    doc.text(20, 20, "Property Name Goes Here");
    doc.text(20, 30, "Budgeted Year:");
    //  doc.text(50, 30, grossItems.owner.company);
    doc.setTextColor(0, 0, 0);
    doc.text(20, 40, "Actual Occupancy:"); 
    //  doc.text(55, 40, grossItems.owner.actual);
    doc.autoTable(col, rows, {
      theme: "plain",
      startY: 45,
      margin: {
        top: 45
      },
      drawHeaderRow: (head, data) => {
        data.doc.setLineWidth(0.7);
        data.doc.setDrawColor(0, 0, 0); // draw black lines
        // Write the line at the top of header
        data.doc.line(
          data.cursor.x,
          data.cursor.y,
          data.cursor.x   data.table.width,
          data.cursor.y
        );
        // Write the line at the bottom of header
        data.doc.line(
          data.cursor.x,
          data.cursor.y   head.height,
          data.cursor.x   data.table.width,
          data.cursor.y   head.height
        );
      }
    });
    doc.autoTable(col1, rows, {
      theme: "plain",
      startY: 100,
      margin: {
        top: 100
      },

      drawHeaderRow: (head, data) => {
        data.doc.setLineWidth(0.7);
        data.doc.setDrawColor(0, 0, 0); // draw black lines
        // Write the line at the top of header
        data.doc.line(
          data.cursor.x,
          data.cursor.y,
          data.cursor.x   data.table.width,
          data.cursor.y
        );
        // Write the line at the bottom of header
        data.doc.line(
          data.cursor.x,
          data.cursor.y   head.height,
          data.cursor.x   data.table.width,
          data.cursor.y   head.height
        );
      }
    });
    document
      .getElementById("convertToPdf")
      .setAttribute("src", doc.output("datauri"));
 }
}
  

Комментарии:

1. Привет, спасибо за ответ, но поскольку это массив объектов, я не могу ожидать, что grossItems[0] будет только там, у него также может быть массив объектов, поэтому он должен динамически принимать значения

2. итак, вы хотели сказать, что `grossItems` может быть либо объектом, либо массивом??

3. да, прямо сейчас у него есть только один объект, в будущем у него может быть несколько объектов

4. Итак, как мне нужно, в таблице мы получаем столбцы, затем в ней изначально отображаются фактические значения объекта Total, затем фактические расходы имеют набор категорий, и у этих категорий есть свои собственные расходы, поэтому названия расходов будут, например, в row1 и row2, и будет отображаться название последней категории, поэтому оно должно продолжаться для всех

5. Все, что я могу сказать, это попытаться узнать typeof (ключевое слово), сравнить с объектом, а затем действовать соответствующим образом. Извините, что немного увлекся.