Pdf 如何使用JDBC库在googlecloudsql中存储Blob
我正在使用一个GoogleApps脚本,它在发布时向用户显示一个HTML页面。我在网页上添加了一个文件输入字段,这样就可以上传PDF和各种格式的图像。接下来,我想获取上传的文件,通过运行Google.script.run将其返回到Google脚本,然后在函数中将该文件作为Blob存储在我的Google Cloud SQL数据库中 以下是我迄今为止的一些代码: HTML: 谷歌脚本: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
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();
}