mirror of
https://github.com/processing/processing4.git
synced 2026-02-04 06:09:17 +01:00
add (simple) ODS writer to Table
This commit is contained in:
@@ -25,6 +25,7 @@ package processing.data;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
@@ -34,6 +35,7 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
@@ -292,7 +294,7 @@ public class Table {
|
||||
|
||||
|
||||
static final String[] loadExtensions = { "csv", "tsv", "ods", "bin" };
|
||||
static final String[] saveExtensions = { "csv", "tsv", "html", "bin" };
|
||||
static final String[] saveExtensions = { "csv", "tsv", "ods", "bin", "html" };
|
||||
|
||||
static public String extensionOptions(boolean loading, String filename, String options) {
|
||||
String extension = PApplet.checkExtension(filename);
|
||||
@@ -971,6 +973,13 @@ public class Table {
|
||||
writeCSV(writer);
|
||||
} else if (extension.equals("tsv")) {
|
||||
writeTSV(writer);
|
||||
} else if (extension.equals("ods")) {
|
||||
try {
|
||||
saveODS(output);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
} else if (extension.equals("html")) {
|
||||
writeHTML(writer);
|
||||
} else if (extension.equals("bin")) {
|
||||
@@ -1140,6 +1149,205 @@ public class Table {
|
||||
}
|
||||
|
||||
|
||||
protected void saveODS(OutputStream os) throws IOException {
|
||||
ZipOutputStream zos = new ZipOutputStream(os);
|
||||
|
||||
final String xmlHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
||||
|
||||
ZipEntry entry = new ZipEntry("META-INF/manifest.xml");
|
||||
String[] lines = new String[] {
|
||||
xmlHeader,
|
||||
"<manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\">",
|
||||
" <manifest:file-entry manifest:media-type=\"application/vnd.oasis.opendocument.spreadsheet\" manifest:version=\"1.2\" manifest:full-path=\"/\"/>",
|
||||
" <manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"content.xml\"/>",
|
||||
" <manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"styles.xml\"/>",
|
||||
" <manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"meta.xml\"/>",
|
||||
" <manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"settings.xml\"/>",
|
||||
"</manifest:manifest>"
|
||||
};
|
||||
zos.putNextEntry(entry);
|
||||
zos.write(PApplet.join(lines, "\n").getBytes());
|
||||
zos.closeEntry();
|
||||
|
||||
/*
|
||||
entry = new ZipEntry("meta.xml");
|
||||
lines = new String[] {
|
||||
xmlHeader,
|
||||
"<office:document-meta office:version=\"1.0\"" +
|
||||
" xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" />"
|
||||
};
|
||||
zos.putNextEntry(entry);
|
||||
zos.write(PApplet.join(lines, "\n").getBytes());
|
||||
zos.closeEntry();
|
||||
|
||||
entry = new ZipEntry("meta.xml");
|
||||
lines = new String[] {
|
||||
xmlHeader,
|
||||
"<office:document-settings office:version=\"1.0\"" +
|
||||
" xmlns:config=\"urn:oasis:names:tc:opendocument:xmlns:config:1.0\"" +
|
||||
" xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"" +
|
||||
" xmlns:ooo=\"http://openoffice.org/2004/office\"" +
|
||||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\" />"
|
||||
};
|
||||
zos.putNextEntry(entry);
|
||||
zos.write(PApplet.join(lines, "\n").getBytes());
|
||||
zos.closeEntry();
|
||||
|
||||
entry = new ZipEntry("settings.xml");
|
||||
lines = new String[] {
|
||||
xmlHeader,
|
||||
"<office:document-settings office:version=\"1.0\"" +
|
||||
" xmlns:config=\"urn:oasis:names:tc:opendocument:xmlns:config:1.0\"" +
|
||||
" xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"" +
|
||||
" xmlns:ooo=\"http://openoffice.org/2004/office\"" +
|
||||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\" />"
|
||||
};
|
||||
zos.putNextEntry(entry);
|
||||
zos.write(PApplet.join(lines, "\n").getBytes());
|
||||
zos.closeEntry();
|
||||
|
||||
entry = new ZipEntry("styles.xml");
|
||||
lines = new String[] {
|
||||
xmlHeader,
|
||||
"<office:document-styles office:version=\"1.0\"" +
|
||||
" xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" />"
|
||||
};
|
||||
zos.putNextEntry(entry);
|
||||
zos.write(PApplet.join(lines, "\n").getBytes());
|
||||
zos.closeEntry();
|
||||
*/
|
||||
|
||||
final String[] dummyFiles = new String[] {
|
||||
"meta.xml", "settings.xml", "styles.xml"
|
||||
};
|
||||
lines = new String[] {
|
||||
xmlHeader,
|
||||
"<office:document-meta office:version=\"1.0\"" +
|
||||
" xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" />"
|
||||
};
|
||||
byte[] dummyBytes = PApplet.join(lines, "\n").getBytes();
|
||||
for (String filename : dummyFiles) {
|
||||
entry = new ZipEntry(filename);
|
||||
zos.putNextEntry(entry);
|
||||
zos.write(dummyBytes);
|
||||
zos.closeEntry();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
entry = new ZipEntry("mimetype");
|
||||
zos.putNextEntry(entry);
|
||||
zos.write("application/vnd.oasis.opendocument.spreadsheet".getBytes());
|
||||
zos.closeEntry();
|
||||
|
||||
//
|
||||
|
||||
entry = new ZipEntry("content.xml");
|
||||
zos.putNextEntry(entry);
|
||||
//lines = new String[] {
|
||||
writeUTF(zos, new String[] {
|
||||
xmlHeader,
|
||||
"<office:document-content" +
|
||||
" xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"" +
|
||||
" xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\"" +
|
||||
" xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\"" +
|
||||
" office:version=\"1.2\">",
|
||||
" <office:body>",
|
||||
" <office:spreadsheet>",
|
||||
" <table:table table:name=\"Sheet1\" table:print=\"false\">"
|
||||
});
|
||||
//zos.write(PApplet.join(lines, "\n").getBytes());
|
||||
|
||||
byte[] rowStart = " <table:table-row>\n".getBytes();
|
||||
byte[] rowStop = " </table:table-row>\n".getBytes();
|
||||
|
||||
if (hasColumnTitles()) {
|
||||
zos.write(rowStart);
|
||||
for (int i = 0; i < getColumnCount(); i++) {
|
||||
saveStringODS(zos, columnTitles[i]);
|
||||
}
|
||||
zos.write(rowStop);
|
||||
}
|
||||
|
||||
for (TableRow row : rows()) {
|
||||
zos.write(rowStart);
|
||||
for (int i = 0; i < getColumnCount(); i++) {
|
||||
if (columnTypes[i] == STRING || columnTypes[i] == CATEGORY) {
|
||||
saveStringODS(zos, row.getString(i));
|
||||
} else {
|
||||
saveNumberODS(zos, row.getString(i));
|
||||
}
|
||||
}
|
||||
zos.write(rowStop);
|
||||
}
|
||||
|
||||
//lines = new String[] {
|
||||
writeUTF(zos, new String[] {
|
||||
" </table:table>",
|
||||
" </office:spreadsheet>",
|
||||
" </office:body>",
|
||||
"</office:document-content>"
|
||||
});
|
||||
//zos.write(PApplet.join(lines, "\n").getBytes());
|
||||
zos.closeEntry();
|
||||
|
||||
zos.flush();
|
||||
zos.close();
|
||||
}
|
||||
|
||||
|
||||
void saveStringODS(OutputStream output, String text) throws IOException {
|
||||
// At this point, I should have just used the XML library. But this does
|
||||
// save us from having to create the entire document in memory again before
|
||||
// writing to the file. So while it's dorky, the outcome is still useful.
|
||||
StringBuilder sanitized = new StringBuilder();
|
||||
char[] array = text.toCharArray();
|
||||
for (char c : array) {
|
||||
if (c == '&') {
|
||||
sanitized.append("&");
|
||||
} else if (c == '\'') {
|
||||
sanitized.append("'");
|
||||
} else if (c == '"') {
|
||||
sanitized.append(""");
|
||||
} else if (c == '<') {
|
||||
sanitized.append("<");
|
||||
} else if (c == '>') {
|
||||
sanitized.append("&rt;");
|
||||
} else if (c < 32 || c > 127) {
|
||||
sanitized.append("&#" + ((int) c) + ";");
|
||||
} else {
|
||||
sanitized.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
writeUTF(output,
|
||||
" <table:table-cell office:value-type=\"string\">",
|
||||
" <text:p>" + sanitized + "</text:p>",
|
||||
" </table:table-cell>");
|
||||
}
|
||||
|
||||
|
||||
void saveNumberODS(OutputStream output, String text) throws IOException {
|
||||
writeUTF(output,
|
||||
" <table:table-cell office:value-type=\"float\" office:value=\"" + text + "\">",
|
||||
" <text:p>" + text + "</text:p>",
|
||||
" </table:table-cell>");
|
||||
}
|
||||
|
||||
|
||||
static Charset utf8;
|
||||
|
||||
static void writeUTF(OutputStream output, String... lines) throws IOException {
|
||||
if (utf8 == null) {
|
||||
utf8 = Charset.forName("UTF-8");
|
||||
}
|
||||
for (String str : lines) {
|
||||
output.write(str.getBytes(utf8));
|
||||
output.write('\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void saveBinary(OutputStream os) throws IOException {
|
||||
DataOutputStream output = new DataOutputStream(new BufferedOutputStream(os));
|
||||
output.writeInt(0x9007AB1E); // version
|
||||
|
||||
Reference in New Issue
Block a user