如何使用JDBC库将Blob存储在Google Cloud SQL中

时间:2017-01-16 22:43:17

标签: pdf jdbc google-apps-script blob google-cloud-sql

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

到目前为止,这是我的一些代码:

HTML:

<input type="file" id="cert">
<input type="button" id="btnCheck" onclick="readFiles()" value="Read Files">

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);
      }
    }
  }
}

Google Script:

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();
}

现在对于手头的问题。此时数据存储在数据库中,但似乎附加了许多额外信息,当我使用MySQL Workbench将数据导出到文件时(在这种情况下我用PDF测试)文件无法打开。

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

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


    %PDF-1.3
    %âãÏÓ
    1 0 obj
    > 
    endobj
    2 0 obj
    > 
    stream
    ÿØÿà JFIF ,,  ÿÛ  

    
    
    

使用Google Apps脚本存储时(前20行):


    %PDF-1.3
    %âãÃÃ
    1 0 obj
    > 
    endobj
    2 0 obj
    > 
    stream
    ÿÃÿà JFIF ,,  ÿà  

    
    
    
    

我可以发送到我的Google脚本功能,但收到的二进制字符串似乎合法。 newBlob是一个JdbcBlob,我使用setBytes函数设置它的第二个参数类型为BlobSource,所以我创建一个Blob用作BlobSource,使用Utilities.newBlob和来自网页的文件二进制字符串作为它的输入。 results.updateBlob的第二个参数类型为JdbcBlob,因此我在这里提供newBlob作为输入。

我非常感谢帮助,因为我现在很难过。谢谢!

1 个答案:

答案 0 :(得分:1)

好吧,看起来我找到了解决方案!

使用函数btoa(...)将二进制字符串结果从FileReader编码到Base64。然后在Google Script中使用Utilities.base64Decode(...)将数据作为Blob获取。

JavaScript的:

x(-1)

Google Script:

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);
      }
    }
  }
}