Repository: caxlsx/caxlsx (Ruby)

Issue:
Broken (not strict) xlsx with rubyzip >=3.0.0
We have issues with opening xlsx generated files within google sheets.
Import to google sheets not working due to "may be damaged" error.
Even a basic example from the readme does not work:

```
p = Axlsx::Package.new
p.workbook.add_worksheet(:name => "Basic Worksheet") do |sheet|
  sheet.add_row ["First Column", "Second", "Third"]
  sheet.add_row [1, 2, 3]
end
p.use_shared_strings = true
p.serialize('simple.xlsx')
```

results in `This file couldn't be imported because it may be damaged. Save a copy and try importing again.`

<img width="639" height="400" alt="Image" src="https://github.com/user-attachments/assets/16924603-d808-47d8-b1f8-84894f682f74" />

`gemspec`

```
caxlsx (4.2.0)
htmlentities (4.3.4)
marcel (1.0.4)
nokogiri (1.18.9)
rubyzip (3.0.2)
```

We updated rubyzip to version 3.0.2 (from 1.3.0) and caxlsx from 4.1.0 to 4.2.0

It is working with rubyzip `2.4.1`


Discussion:
I figured out the reason.

https://github.com/rubyzip/rubyzip?tab=readme-ov-file#zip64-support

> Since version 3.0, Zip64 support is enabled for writing by default

By disabling this in e.g. an initializer, generating non broken xlsx files do work again:

```ruby
Zip.write_zip64_support = false
```
hi @forelabs , thanks for reporting this issue. I've created a PR to fix this, please take a look at it



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fee9b150..fb4712bf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
 CHANGELOG
 ---------
 - **Unreleased**
+  - [PR #482](https://github.com/caxlsx/caxlsx/pull/482) Suppress Zip64 when it't not necessary
 
 - **September.01.25**: 4.4.0
   - [PR #477](https://github.com/caxlsx/caxlsx/pull/477) Add package-level encryption and password protection.
diff --git a/lib/axlsx/util/buffered_zip_output_stream.rb b/lib/axlsx/util/buffered_zip_output_stream.rb
index 7d93919a..2b9949d8 100644
--- a/lib/axlsx/util/buffered_zip_output_stream.rb
+++ b/lib/axlsx/util/buffered_zip_output_stream.rb
@@ -9,6 +9,10 @@ class BufferedZipOutputStream
     # The 4_096 was chosen somewhat arbitrary, however, it was difficult to see any obvious improvement with larger
     # buffer sizes.
     BUFFER_SIZE = 4_096
+    # The suppress_extra_fields method was introduced in rubyzip 3.2
+    # Between rubyzip 3.0 and 3.2, it automatically writes zip64 support to the xlsx files
+    # See: https://github.com/caxlsx/caxlsx/issues/481
+    SUPPRESS_ZIP64 = Zip::OutputStream.method(:open).parameters.any? { |_, key| key == :suppress_extra_fields } ? { suppress_extra_fields: :zip64 } : {}
 
     def initialize(zos)
       @zos = zos
@@ -19,7 +23,7 @@ def initialize(zos)
     #
     # The directory and its contents are removed at the end of the block.
     def self.open(file_name, encrypter = nil)
-      Zip::OutputStream.open(file_name, encrypter: encrypter) do |zos|
+      Zip::OutputStream.open(file_name, encrypter: encrypter, **SUPPRESS_ZIP64) do |zos|
         bzos = new(zos)
         yield(bzos)
       ensure
@@ -28,7 +32,7 @@ def self.open(file_name, encrypter = nil)
     end
 
     def self.write_buffer(io = ::StringIO.new, encrypter = nil)
-      Zip::OutputStream.write_buffer(io, encrypter: encrypter) do |zos|
+      Zip::OutputStream.write_buffer(io, encrypter: encrypter, **SUPPRESS_ZIP64) do |zos|
         bzos = new(zos)
         yield(bzos)
       ensure


Test patch:
diff --git a/test/tc_package.rb b/test/tc_package.rb
index 4b7fa08b..eb4de671 100644
--- a/test/tc_package.rb
+++ b/test/tc_package.rb
@@ -136,6 +136,7 @@ def test_serialization
 
     assert_zip_file_matches_package(@fname, @package)
     assert_created_with_rubyzip(@fname, @package)
+    assert_zip_file_has_no_zip64(@fname)
     File.delete(@fname)
   end
 
@@ -228,6 +229,14 @@ def assert_zip_file_matches_package(fname, package)
     package.send(:parts).each { |part| zf.get_entry(part[:entry]) }
   end
 
+  def assert_zip_file_has_no_zip64(fname)
+    return unless defined?(Zip::VERSION) && Zip::VERSION >= '3.2'
+
+    zf = Zip::File.open(fname)
+
+    assert(zf.entries.none?(&:zip64?))
+  end
+
   def assert_created_with_rubyzip(fname, package)
     assert_equal 2098, get_mtime(fname, package).year, "XLSX files created with RubyZip have 2098 as the file mtime"
   end