- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在尝试以编程方式修改 excel 文件 (xlsx)。我可以成功解压,根据需要修改xml,然后重新压缩。但是,每次我打开 excel 时都会收到警告,即使它确实读取了文件。我相信错误是由于使用的压缩方法造成的。这是我能得到的最接近的示例:
解压
7z x original.xlsx -o./decomp_xlsx
..做一些事情..
压缩
7z a -tzip new ./decomp_xlsx/*
重命名
mv ./new.zip ./new.xlsx
我得到的错误是:Excel 在“new.xlsx”中发现不可读的内容。是否要恢复此工作簿的内容?如果您信任此工作簿的来源,请单击"is"。
来自 ECMA-376-2 Office 开放格式第 2 部分(打包约定)支持的压缩算法是 DEFLATE,如 .ZIP 规范中所述。包实现者不得使用除 DEFLATE 之外的任何压缩算法。
那么,我需要在 7z 或其他 linux 兼容程序中使用哪些开关才能在没有警告的情况下完成工作?我试过删除 -tzip 并使用 -m0=COPY,但 excel 甚至无法从那个中恢复。
这是 zip 程序和 zipinfo 的结果。我猜我不会找到一个工具来做这件事,除了下面提供的那个,所以我要奖励那个答案,看看我是否能找到人翻译成 python 进行测试。我不确定它是否处理了 4.5/3.0、b-/tx 或 defS/defF 之间的差异。
$ zipinfo original.xlsx
Archive: original.xlsx
Zip file size: 228039 bytes, number of entries: 20
-rw---- 4.5 fat 1969 b- defS 80-Jan-01 00:00 [Content_Types].xml
-rw---- 4.5 fat 588 b- defS 80-Jan-01 00:00 _rels/.rels
-rw---- 4.5 fat 1408 b- defS 80-Jan-01 00:00 xl/_rels/workbook.xml.rels
-rw---- 4.5 fat 908 b- defS 80-Jan-01 00:00 xl/workbook.xml
-rw---- 4.5 fat 35772 b- defS 80-Jan-01 00:00 xl/worksheets/sheet4.xml
-rw---- 4.5 fat 322 b- defS 80-Jan-01 00:00 xl/worksheets/_rels/sheet4.xml.rels
-rw---- 4.5 fat 322 b- defS 80-Jan-01 00:00 xl/worksheets/_rels/sheet1.xml.rels
-rw---- 4.5 fat 230959 b- defS 80-Jan-01 00:00 xl/worksheets/sheet2.xml
-rw---- 4.5 fat 263127 b- defS 80-Jan-01 00:00 xl/worksheets/sheet3.xml
-rw---- 4.5 fat 295775 b- defS 80-Jan-01 00:00 xl/worksheets/sheet1.xml
-rw---- 4.5 fat 1947 b- defS 80-Jan-01 00:00 xl/sharedStrings.xml
-rw---- 4.5 fat 22698 b- defS 80-Jan-01 00:00 xl/styles.xml
-rw---- 4.5 fat 7079 b- defS 80-Jan-01 00:00 xl/theme/theme1.xml
-rw---- 4.5 fat 220 b- defS 80-Jan-01 00:00 xl/printerSettings/printerSettings2.bin
-rw---- 4.5 fat 464247 b- defS 80-Jan-01 00:00 xl/externalLinks/externalLink1.xml
-rw---- 4.5 fat 338 b- defS 80-Jan-01 00:00 xl/externalLinks/_rels/externalLink1.xml.rels
-rw---- 4.5 fat 220 b- defS 80-Jan-01 00:00 xl/printerSettings/printerSettings1.bin
-rw---- 4.5 fat 593 b- defS 80-Jan-01 00:00 docProps/core.xml
-rw---- 4.5 fat 62899 b- defS 80-Jan-01 00:00 xl/calcChain.xml
-rw---- 4.5 fat 1031 b- defS 80-Jan-01 00:00 docProps/app.xml
20 files, 1392422 bytes uncompressed, 223675 bytes compressed: 83.9%
$ zipinfo new.xlsx
Archive: new.xlsx
Zip file size: 233180 bytes, number of entries: 20
-rw-r--r-- 3.0 unx 1031 tx defF 80-Jan-01 00:00 docProps/app.xml
-rw-r--r-- 3.0 unx 593 tx defF 80-Jan-01 00:00 docProps/core.xml
-rw-r--r-- 3.0 unx 62899 tx defF 80-Jan-01 00:00 xl/calcChain.xml
-rw-r--r-- 3.0 unx 464247 tx defF 80-Jan-01 00:00 xl/externalLinks/externalLink1.xml
-rw-r--r-- 3.0 unx 338 tx defF 80-Jan-01 00:00 xl/externalLinks/_rels/externalLink1.xml.rels
-rw-r--r-- 3.0 unx 220 bx defF 80-Jan-01 00:00 xl/printerSettings/printerSettings1.bin
-rw-r--r-- 3.0 unx 220 bx defF 80-Jan-01 00:00 xl/printerSettings/printerSettings2.bin
-rw-r--r-- 3.0 unx 1947 tx defF 80-Jan-01 00:00 xl/sharedStrings.xml
-rw-r--r-- 3.0 unx 22698 tx defF 80-Jan-01 00:00 xl/styles.xml
-rw-r--r-- 3.0 unx 7079 tx defF 80-Jan-01 00:00 xl/theme/theme1.xml
-rw-r--r-- 3.0 unx 908 tx defF 80-Jan-01 00:00 xl/workbook.xml
-rw-r--r-- 3.0 unx 295775 tx defF 80-Jan-01 00:00 xl/worksheets/sheet1.xml
-rw-r--r-- 3.0 unx 230959 tx defF 80-Jan-01 00:00 xl/worksheets/sheet2.xml
-rw-r--r-- 3.0 unx 263127 tx defF 80-Jan-01 00:00 xl/worksheets/sheet3.xml
-rw-r--r-- 3.0 unx 35772 tx defF 80-Jan-01 00:00 xl/worksheets/sheet4.xml
-rw-r--r-- 3.0 unx 322 tx defF 80-Jan-01 00:00 xl/worksheets/_rels/sheet1.xml.rels
-rw-r--r-- 3.0 unx 322 tx defF 80-Jan-01 00:00 xl/worksheets/_rels/sheet4.xml.rels
-rw-r--r-- 3.0 unx 1408 tx defF 80-Jan-01 00:00 xl/_rels/workbook.xml.rels
-rw-r--r-- 3.0 unx 1969 tx defF 80-Jan-01 00:00 [Content_Types].xml
-rw-r--r-- 3.0 unx 588 tx defF 80-Jan-01 00:00 _rels/.rels
20 files, 1392422 bytes uncompressed, 229608 bytes compressed: 83.5%
最佳答案
出于某种奇怪的原因,微软正在本地文件头和中央目录头中查看“需要提取的版本”中的操作系统编码。它希望这些为零,但 7z 将它们设置为 3 for Unix。如果您打算使用 7z,则需要修补生成的文件。
这个程序会这样做:
/* needz.c - zero the operating system byte for "version needed to extract" in
the local and central headers of the zip files given on the command line.
Placed in the public domain by Mark Adler, 23 Feb 2013. */
#include <stdio.h>
#include <stdlib.h>
static void bail(char *why, char *what)
{
fprintf(stderr, "needz error: %s%s\n", why, what);
exit(1);
}
/* Read len bytes from offset as a little-endian integer. Negative offsets are
considered to be from the end of the file. */
static unsigned long peek(FILE *stream, off_t offset, int len)
{
int ret, shift;
unsigned long val;
ret = fseeko(stream, offset, offset < 0 ? SEEK_END : SEEK_SET);
if (ret)
bail("not a zip file", "");
val = 0;
shift = 0;
while (len--) {
ret = getc(stream);
if (ret == EOF)
bail("not a zip file", "");
val += (unsigned long)ret << shift;
shift += 8;
}
return val;
}
/* Write len bytes to offset from val as a little-endian integer. Negative
offsets are considered to be from the end of the file. */
static void poke(FILE *stream, off_t offset, int len, unsigned long val)
{
int ret;
ret = fseeko(stream, offset, offset < 0 ? SEEK_END : SEEK_SET);
if (ret)
bail("not a zip file", "");
while (len--) {
ret = putc(val, stream);
if (ret == EOF)
bail("could not write", "");
val >>= 8;
}
}
/* Zero out the OS byte in the extract fields. This assumes the classic zip
format (not Zip64), and no zip file comment. */
static void zip_zero_os(char *path)
{
FILE *zip;
unsigned entries;
off_t central, local;
zip = fopen(path, "r+b");
if (zip == NULL)
bail("could not open", path);
if (peek(zip, -22, 4) != 0x06054b50)
bail(path, " is not a zip file or has an end comment");
entries = peek(zip, -12, 2);
central = peek(zip, -6, 4);
while (entries--) {
if (peek(zip, central, 4) != 0x02014b50)
bail(path, " has a structure error or is Zip64");
poke(zip, central + 7, 1, 0);
local = peek(zip, central + 42, 4);
if (peek(zip, local, 4) != 0x04034b50)
bail(path, " has a structure error or is Zip64");
poke(zip, local + 5, 1, 0);
central += 46 + peek(zip, central + 28, 2) +
peek(zip, central + 30, 2) + peek(zip, central + 32, 2);
}
if (fclose(zip) == EOF)
bail("could not close ", path);
}
int main(int argc, char **argv)
{
while (--argc)
zip_zero_os(*++argv);
return 0;
}
关于linux - xlsx 与 7z 的压缩方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15033646/
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!