Pdf 如何使用JDBC库在googlecloudsql中存储Blob

Pdf 如何使用JDBC库在googlecloudsql中存储Blob,pdf,jdbc,google-apps-script,blob,google-cloud-sql,Pdf,Jdbc,Google Apps Script,Blob,Google Cloud Sql,我正在使用一个GoogleApps脚本,它在发布时向用户显示一个HTML页面。我在网页上添加了一个文件输入字段,这样就可以上传PDF和各种格式的图像。接下来,我想获取上传的文件,通过运行Google.script.run将其返回到Google脚本,然后在函数中将该文件作为Blob存储在我的Google Cloud SQL数据库中 以下是我迄今为止的一些代码: HTML: 谷歌脚本: function storeFile(f) { var conn = Jdbc.getConnection(d

我正在使用一个GoogleApps脚本,它在发布时向用户显示一个HTML页面。我在网页上添加了一个文件输入字段,这样就可以上传PDF和各种格式的图像。接下来,我想获取上传的文件,通过运行Google.script.run将其返回到Google脚本,然后在函数中将该文件作为Blob存储在我的Google Cloud SQL数据库中

以下是我迄今为止的一些代码:

HTML:

谷歌脚本:

function storeFile(f) {
  var conn = Jdbc.getConnection(dbUrl, user, userPwd);
  var stmt = conn.createStatement(Jdbc.ResultSet.TYPE_SCROLL_INSENSITIVE, Jdbc.ResultSet.CONCUR_UPDATABLE);

  var results = stmt.executeQuery('select * from my_table');

  results.moveToInsertRow();

  var newBlob = conn.createBlob();
  var uBlob = Utilities.newBlob(f, 'application/pdf');
  newBlob.setBytes(1, uBlob.getBytes());

  results.updateBlob('file', newBlob);

  results.insertRow();
  results.moveToCurrentRow();

  results.close();
  stmt.close();
}
function storeFile(f) {
  var conn = Jdbc.getConnection(dbUrl, user, userPwd);
  var stmt = conn.createStatement(Jdbc.ResultSet.TYPE_SCROLL_INSENSITIVE, Jdbc.ResultSet.CONCUR_UPDATABLE);

  var results = stmt.executeQuery('select * from my_table');

  results.moveToInsertRow();

  var newBlob = conn.createBlob();
  newBlob.setBytes(1, Utilities.base64Decode(f));

  results.updateBlob('file', newBlob);

  results.insertRow();
  results.moveToCurrentRow();

  results.close();
  stmt.close();
}
那么现在来谈谈手头的问题。此时,数据存储在数据库中,但似乎附加了很多额外信息,当我使用MySQL Workbench将数据导出到文件(在本例中,我使用PDF进行测试)时,文件无法打开

如果我使用MySQL Workbench手动将一个文件插入数据库,数据大小正确,可以导出,并且可以正常打开。我注意到,如果我打印uBlob.getBytes()的大小,值是754244,如果我打印uBlob.getDataAsString()的大小,值是528004。原始文件大小为516kB(~528384)。从原始数据来看,它们肯定有相似之处,请注意下面的内容

使用MySQL Workbench存储时(前20行):

%PDF-1.3 %âãÏÓ 10 obj > endobj 20 obj > 流动 ÿØÿa¦JFIF,,ÿÛ  使用Google Apps脚本存储时(前20行):

%PDF-1.3 %âãÃà 10 obj > endobj 20 obj > 流动 ÃÃÃÃJFIF,,Ãà  我的Google脚本函数的发送内容有限,但收到的二进制字符串似乎是合法的。newBlob是一个JdbcBlob,我正在使用setBytes函数设置它,其第二个参数的类型为BlobSource,因此我正在使用Utilities.newBlob创建一个Blob作为BlobSource,并将网页中的文件二进制字符串作为其输入。updateBlob有其类型为JdbcBlob的第二个参数,所以这里我提供了newBlob作为输入


我很感激你的帮助,因为我在这一点上被难住了。谢谢

好吧,看来我找到了解决办法

使用函数btoa(…)将文件读取器中的二进制字符串结果编码为Base64。然后在Google脚本中使用Utilities.base64Decode(…)以Blob的形式获取数据

JavaScript:

function readFiles() {
  var x = document.getElementById("cert");
  if ('files' in x) {
    if (x.files.length != 0) {
      for (var i = 0, f; f = x.files[i]; i++) {
        var reader = new FileReader();
        // Closure to capture the file information.
        reader.onload = (function(theFile) {
          return function(e) {
            google.script.run.storeFile(e.target.result);
          };
        })(f);
        reader.readAsBinaryString(f);
      }
    }
  }
}
function readFiles() {
  var x = document.getElementById("cert");
  if ('files' in x) {
    if (x.files.length != 0) {
      for (var i = 0, f; f = x.files[i]; i++) {
        var reader = new FileReader();
        // Closure to capture the file information.
        reader.onload = (function(theFile) {
          return function(e) {
            google.script.run.storeFile(btoa(e.target.result));
          };
        })(f);
        reader.readAsBinaryString(f);
      }
    }
  }
}
谷歌脚本:

function storeFile(f) {
  var conn = Jdbc.getConnection(dbUrl, user, userPwd);
  var stmt = conn.createStatement(Jdbc.ResultSet.TYPE_SCROLL_INSENSITIVE, Jdbc.ResultSet.CONCUR_UPDATABLE);

  var results = stmt.executeQuery('select * from my_table');

  results.moveToInsertRow();

  var newBlob = conn.createBlob();
  var uBlob = Utilities.newBlob(f, 'application/pdf');
  newBlob.setBytes(1, uBlob.getBytes());

  results.updateBlob('file', newBlob);

  results.insertRow();
  results.moveToCurrentRow();

  results.close();
  stmt.close();
}
function storeFile(f) {
  var conn = Jdbc.getConnection(dbUrl, user, userPwd);
  var stmt = conn.createStatement(Jdbc.ResultSet.TYPE_SCROLL_INSENSITIVE, Jdbc.ResultSet.CONCUR_UPDATABLE);

  var results = stmt.executeQuery('select * from my_table');

  results.moveToInsertRow();

  var newBlob = conn.createBlob();
  newBlob.setBytes(1, Utilities.base64Decode(f));

  results.updateBlob('file', newBlob);

  results.insertRow();
  results.moveToCurrentRow();

  results.close();
  stmt.close();
}

另一种方法是将其存储在驱动器中,然后将文件id保存在sql中。这些文件将由多个用户上载,并且可能会非常多,因此出于多种原因,我更愿意将它们保存在数据库存储中。1) 它不会计入我的个人硬盘配额,2)文件保持相对有序,3)如果系统需要移动到Google域之外,我可以备份数据库并移动到另一台服务器,而不会丢失数据完整性。不过还是个好主意,谢谢你!尽管如此,还是要尝试保存到驱动器,看看是否会遇到同样的问题,只是为了解决问题。好吧,我从驱动器中打开了一个PDF,并能够将其存储在数据库中,然后打开MySQL Workbench并将Blob导出到一个文件中,然后成功地打开了该文件。因此我假设问题在于以下几行:var uBlob=Utilities.newBlob(f,'application/pdf');newBlob.setBytes(1,uBlob.getBytes());
function storeFile(f) {
  var conn = Jdbc.getConnection(dbUrl, user, userPwd);
  var stmt = conn.createStatement(Jdbc.ResultSet.TYPE_SCROLL_INSENSITIVE, Jdbc.ResultSet.CONCUR_UPDATABLE);

  var results = stmt.executeQuery('select * from my_table');

  results.moveToInsertRow();

  var newBlob = conn.createBlob();
  newBlob.setBytes(1, Utilities.base64Decode(f));

  results.updateBlob('file', newBlob);

  results.insertRow();
  results.moveToCurrentRow();

  results.close();
  stmt.close();
}