Vue js에서 이미지를 동적 테이블에서 base64 형식으로 변환하고 json 파일로 보내는 방법??

10386 단어 vuewebdevjavascript
Dears, 각 행에 다른 이미지가 있는 여러 행을 추가하는 동적 테이블이 있습니다. 이미지를 base64 형식으로 변환하고 변환된 base64 이미지가 있는 테이블을 json 파일로 저장하려고 했습니다. json 파일에는 첫 번째로 base64 텍스트만 포함되어 있는 문제가 있습니다. 모든 테이블 행의 이미지, json 파일에 테이블의 다른 이미지에 대한 모든 base64 텍스트가 포함되기를 원합니다. 귀하의 도움을 높이 평가합니다

다음은 vue js의 평가판입니다.

<template>
<v-container>
    <v-form lazy-validation ref="form">
      <v-card class="pa-5">
        <v-list-item-title class="headline mb-2 pa-1">
          information</v-list-item-title
        >

        <v-row>
          <v-text-field
            class="pa-1"
            label="Field abbreviation"
            @keyup="uppercase"
            required
            v-model="field"
            :rules="fieldRule"
            maxlength="4"
          ></v-text-field>
        </v-row>
        <v-row>
          <v-text-field
            class="pa-1"
            label="Field lines"
            @keyup="uppercase"
            required
            v-model="fieldLines"
          ></v-text-field>
        </v-row>
      </v-card>

      <table class="responsive-table">
        <thead>
          <tr>
            <th scope="col">#</th>

            <th class="text-left">Sample Depth</th>

            <th class="text-left">Sample Number</th>

            <th class="text-left">Zoom Factor</th>

            <th class="text-left">Fossil Image</th>
          </tr>
        </thead>

        <tbody>
          <tr v-for="(imageTable, index) in imageTables" :key="index">
            <td scope="row" class="trashIconContainer">
              <i
                class="far fa-trash-alt"
                @click="deleteimageRow(index, imageTable)"
              ></i>
            </td>

            <td data-label="sampleDepth">
              <input
                v-model="imageTable.sampleDepth"
                class="form-control"
                type="number"
              />
            </td>

            <td data-label="sampleNumber">
              <input
                v-model="imageTable.sampleNumber"
                class="form-control"
                type="number"
              />
            </td>

            <td data-label="ZoomFactor">
              <input
                v-model="imageTable.zoomFactor"
                class="form-control"
                type="number"
              />
            </td>

            <td>
              <v-file-input
                type="file"
                accept="image/png, image/jpeg, image/bmp"
                placeholder="Pick a Fossil photo"
                @change="uploadImage(index)"
              ></v-file-input>
            </td>

            <td>
              <button @click="deleteimageRow" class="is-danger">Delete</button>
            </td>
          </tr>
        </tbody>
      </table>

      <button type="button" class="btn btn-info" @click="addimageRow">
        <i class="fas fa-plus-circle"></i>

        Add
      </button>

      <v-row>
        <v-col>
          <v-btn
            width="100%"
            class="primary"
            :loading="isPdfGenerating"
            @click="generateReport(true)"
            >Generate draft report</v-btn
          >
        </v-col>
      </v-row>

      <v-row>
        <v-col>
          <v-btn
            width="100%"
            class="primary"
            :disabled="!isPdfGenerated"
            @click="savePdf"
            >Download generated report</v-btn
          >
        </v-col>

        <v-col>
          <v-btn
            width="100%"
            class="primary"
            :disabled="!isPdfGenerated"
            @click="generateReport(false)"
            >Make report official</v-btn
          >
        </v-col>
      </v-row>
    </v-form>
  </v-container>
</template>

<script>
export default {
  name: "Table",

  data: () => ({
    field: null,
    fieldRule:[],
    fieldLines: null,
    isPdfGenerating: false,
    isPdfGenerated: false,
    pdfData: null,
    imageUploaded: false,
    imageTables: [
      { sampleDepth: "", sampleNumber: "", zoomFactor: "", image: "" },
    ],
  }),

  created() {},

  methods: {
    addimageRow() {
      this.imageTables.push({
        sampleDepth: "",

        sampleNumber: "",

        zoomFactor: "",

        image: "",
      });  
      console.log(this.imageTables); 
    },

    uppercase(){
      //pass
    },
    deleteimageRow(index, imageTables) {
      var idx = this.imageTables.indexOf(imageTables);

      console.log(idx, index);

      this.imageTables.splice(idx, 2);
    },

    uploadImage(idx) {
      this.imageUploaded = true;
      const file = document.querySelector("input[type=file]").files[0];

      const reader = new FileReader();

      let rawImg;

      reader.onloadend = () => {
        rawImg = reader.result;
        this.imageTables[idx].image = rawImg;
      };
      reader.readAsDataURL(file);
    },

    generateReport: function (isDraft = true) {
      this.$refs.form.validate();

      this.$emit("pdfGenerated", null);

      this.isPdfGenerating = true;

      this.isPdfGenerated = false;

      let jsonData = {
        field: this.field,
        fieldlines: this.fieldLines,

        imageTables: this.imageTables,

        key: this.$store.state.key,

        isDraft: isDraft,
      };

      console.log(jsonData);

      this.$axios
        .post(this.$backendUrl + "/table", jsonData)

        .then((response) => {
          console.log(response);

          this.pdfData = { data: response.data };

          this.$emit("pdfGenerated", this.pdfData);

          this.isPdfGenerated = true;

          this.isPdfGenerating = false;
        })

        .catch((error) => {
          console.log(error);

          this.isPdfGenerating = false;

          this.isPdfGenerated = false;

          if (error.response.status == 401) {
            this.$emit("unauthorized");
          }

          if (error.response.status == 404) {
            window.alert(error.response.data.message);
          }
        })

        .then(function () {});
    },

    savePdf: function () {
      var blob = new Blob([this.pdfData.data], { type: "application/pdf" });

      var link = document.createElement("a");

      link.href = window.URL.createObjectURL(blob);

      var fileName = "Output";

      link.download = fileName;

      link.click();
    },
  }
};
</script>

<style scoped>
@media (min-width: 761px) {
  .header {
    display: flex;
  }
}

@media (min-width: 761px) {
  .header > div:nth-child(-n + 1) {
    order: 1;

    flex: 1;

    text-align: right;

    padding-left: 1rem;
  }
}

.section-spacer {
  margin: 1rem 0;
}

input,
select,
textarea {
  background-color: rgb(245, 243, 237);

  /* background-color:#ffc371; */

  border: none;

  border-top: 2px solid #ffc371;

  border-bottom: 2px solid #ffc371;

  border-left: 2px solid #ffc371;

  border-right: 2px solid #ffc371;

  border-radius: 5px;

  display: inline-block;

  transition: background-color 0.3s ease-in-out;

  width: 100%;
}

input:focus,
select:focus,
textarea:focus {
  outline-color: #ffc371;

  background-color: rgba(255, 255, 255, 0.6);
}

input:hover,
select:hover,
textarea:hover {
  background-color: rgba(255, 255, 255, 0.5);
}

@media print {
  input,
  select,
  textarea {
    background-color: transparent;
  }
}

textarea {
  width: 100%;

  min-height: 80px;
}

table {
  width: auto;

  border-collapse: collapse;

  margin: 4rem 0;
}

table thead th {
  padding: 0.5rem 1rem;
}

table thead th:nth-child(-n + 1) {
  padding-left: 0;
}

table thead th:nth-last-child(-n + 1) {
  padding-right: 0;
}

table tr {
  border-bottom: 1px solid #f4d4aa;
}

table tr td {
  padding: 0.5rem 1rem;
}

table tr td:nth-child(-n + 10) {
  padding-left: 0;
}

table tr td:nth-last-child(-n + 1) {
  padding-right: 0;
}

table tr td input {
  width: 100%;
}

table tr td .cell-with-input input {
  margin: 0 0.2rem;
}

.responsive-table {
  width: 100%;
}

@media only screen and (max-width: 760px) {
  .responsive-table table,
  .responsive-table thead,
  .responsive-table tbody,
  .responsive-table th,
  .responsive-table td,
  .responsive-table tr {
    display: block;
  }

  .responsive-table thead tr {
    position: absolute;

    top: -9999px;

    left: -9999px;
  }

  .responsive-table tr {
    padding: 2rem 0;
  }

  .responsive-table td[data-label] {
    position: relative;

    padding-left: 100;

    display: flex;

    align-items: right;
  }

  .responsive-table td[data-label]:before {
    content: attr(data-label);

    position: absolute;

    top: 0.5rem;

    left: 0;

    width: 35%;

    padding-right: 10px;

    white-space: nowrap;

    font-weight: bold;
  }
}

button {
  background-color: #81cf71;

  border: none;

  border-radius: 100px;

  padding: 0.5rem 1rem;

  cursor: pointer;

  transition: background-color 0.3s ease-in-out;
}

button:focus {
  outline-color: #ffc371;

  background-color: #69c656;
}

button:hover {
  background-color: #70c95e;
}

@media print {
  button {
    display: none;
  }
}

button.is-danger {
  background-color: #ff5f6d;
}

button.is-danger:focus {
  background-color: #ff3b4c;
}

button.is-danger:hover {
  background-color: #ff4656;
}

.text-right {
  text-align: right;
}

.text-bold {
  font-weight: bold;
}
</style>

좋은 웹페이지 즐겨찾기