—###############################################################################
#
# Excel::Writer::XLSX::Package::ContentTypes - A class for writing the Excel
# XLS [Content_Types] file.
#
# Used in conjunction with Excel::Writer::XLSX
#
# Copyright 2000-2024, John McNamara, jmcnamara@cpan.org
#
# SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later
#
# Documentation after __END__
#
# perltidy with the following options: -mbl=2 -pt=0 -nola
use
5.008002;
use
strict;
use
warnings;
use
Carp;
our
@ISA
=
qw(Excel::Writer::XLSX::Package::XMLwriter)
;
our
$VERSION
=
'1.14'
;
###############################################################################
#
# Package data.
#
###############################################################################
my
$app_package
=
'application/vnd.openxmlformats-package.'
;
my
$app_document
=
'application/vnd.openxmlformats-officedocument.'
;
our
@defaults
= (
[
'rels'
,
$app_package
.
'relationships+xml'
],
[
'xml'
,
'application/xml'
],
);
our
@overrides
= (
[
'/docProps/app.xml'
,
$app_document
.
'extended-properties+xml'
],
[
'/docProps/core.xml'
,
$app_package
.
'core-properties+xml'
],
[
'/xl/styles.xml'
,
$app_document
.
'spreadsheetml.styles+xml'
],
[
'/xl/theme/theme1.xml'
,
$app_document
.
'theme+xml'
],
[
'/xl/workbook.xml'
,
$app_document
.
'spreadsheetml.sheet.main+xml'
],
);
###############################################################################
#
# Public and private API methods.
#
###############################################################################
###############################################################################
#
# new()
#
# Constructor.
#
sub
new {
my
$class
=
shift
;
my
$fh
=
shift
;
my
$self
= Excel::Writer::XLSX::Package::XMLwriter->new(
$fh
);
$self
->{_defaults} = [
@defaults
];
$self
->{_overrides} = [
@overrides
];
bless
$self
,
$class
;
return
$self
;
}
###############################################################################
#
# _assemble_xml_file()
#
# Assemble and write the XML file.
#
sub
_assemble_xml_file {
my
$self
=
shift
;
$self
->xml_declaration;
$self
->_write_types();
$self
->_write_defaults();
$self
->_write_overrides();
$self
->xml_end_tag(
'Types'
);
# Close the XML writer filehandle.
$self
->xml_get_fh()->
close
();
}
###############################################################################
#
# _add_default()
#
# Add elements to the ContentTypes defaults.
#
sub
_add_default {
my
$self
=
shift
;
my
$part_name
=
shift
;
my
$content_type
=
shift
;
push
@{
$self
->{_defaults} }, [
$part_name
,
$content_type
];
}
###############################################################################
#
# _add_override()
#
# Add elements to the ContentTypes overrides.
#
sub
_add_override {
my
$self
=
shift
;
my
$part_name
=
shift
;
my
$content_type
=
shift
;
push
@{
$self
->{_overrides} }, [
$part_name
,
$content_type
];
}
###############################################################################
#
# _add_worksheet_name()
#
# Add the name of a worksheet to the ContentTypes overrides.
#
sub
_add_worksheet_name {
my
$self
=
shift
;
my
$worksheet_name
=
shift
;
$worksheet_name
=
"/xl/worksheets/$worksheet_name.xml"
;
$self
->_add_override(
$worksheet_name
,
$app_document
.
'spreadsheetml.worksheet+xml'
);
}
###############################################################################
#
# _add_chartsheet_name()
#
# Add the name of a chartsheet to the ContentTypes overrides.
#
sub
_add_chartsheet_name {
my
$self
=
shift
;
my
$chartsheet_name
=
shift
;
$chartsheet_name
=
"/xl/chartsheets/$chartsheet_name.xml"
;
$self
->_add_override(
$chartsheet_name
,
$app_document
.
'spreadsheetml.chartsheet+xml'
);
}
###############################################################################
#
# _add_chart_name()
#
# Add the name of a chart to the ContentTypes overrides.
#
sub
_add_chart_name {
my
$self
=
shift
;
my
$chart_name
=
shift
;
$chart_name
=
"/xl/charts/$chart_name.xml"
;
$self
->_add_override(
$chart_name
,
$app_document
.
'drawingml.chart+xml'
);
}
###############################################################################
#
# _add_drawing_name()
#
# Add the name of a drawing to the ContentTypes overrides.
#
sub
_add_drawing_name {
my
$self
=
shift
;
my
$drawing_name
=
shift
;
$drawing_name
=
"/xl/drawings/$drawing_name.xml"
;
$self
->_add_override(
$drawing_name
,
$app_document
.
'drawing+xml'
);
}
###############################################################################
#
# _add_vml_name()
#
# Add the name of a VML drawing to the ContentTypes defaults.
#
sub
_add_vml_name {
my
$self
=
shift
;
$self
->_add_default(
'vml'
,
$app_document
.
'vmlDrawing'
);
}
###############################################################################
#
# _add_comment_name()
#
# Add the name of a comment to the ContentTypes overrides.
#
sub
_add_comment_name {
my
$self
=
shift
;
my
$comment_name
=
shift
;
$comment_name
=
"/xl/$comment_name.xml"
;
$self
->_add_override(
$comment_name
,
$app_document
.
'spreadsheetml.comments+xml'
);
}
###############################################################################
#
# _Add_shared_strings()
#
# Add the sharedStrings link to the ContentTypes overrides.
#
sub
_add_shared_strings {
my
$self
=
shift
;
$self
->_add_override(
'/xl/sharedStrings.xml'
,
$app_document
.
'spreadsheetml.sharedStrings+xml'
);
}
###############################################################################
#
# _add_calc_chain()
#
# Add the calcChain link to the ContentTypes overrides.
#
sub
_add_calc_chain {
my
$self
=
shift
;
$self
->_add_override(
'/xl/calcChain.xml'
,
$app_document
.
'spreadsheetml.calcChain+xml'
);
}
###############################################################################
#
# _add_image_types()
#
# Add the image default types.
#
sub
_add_image_types {
my
$self
=
shift
;
my
%types
=
@_
;
for
my
$type
(
keys
%types
) {
$self
->_add_default(
$type
,
'image/'
.
$type
);
}
}
###############################################################################
#
# _add_table_name()
#
# Add the name of a table to the ContentTypes overrides.
#
sub
_add_table_name {
my
$self
=
shift
;
my
$table_name
=
shift
;
$table_name
=
"/xl/tables/$table_name.xml"
;
$self
->_add_override(
$table_name
,
$app_document
.
'spreadsheetml.table+xml'
);
}
###############################################################################
#
# _add_vba_project()
#
# Add a vbaProject to the ContentTypes defaults.
#
sub
_add_vba_project {
my
$self
=
shift
;
# Change the workbook.xml content-type from xlsx to xlsm.
for
my
$aref
( @{
$self
->{_overrides} } ) {
if
(
$aref
->[0] eq
'/xl/workbook.xml'
) {
$aref
->[1] =
'application/vnd.ms-excel.sheet.macroEnabled.main+xml'
;
}
}
$self
->_add_default(
'bin'
,
'application/vnd.ms-office.vbaProject'
);
}
###############################################################################
#
# _add_custom_properties()
#
# Add the custom properties to the ContentTypes overrides.
#
sub
_add_custom_properties {
my
$self
=
shift
;
my
$custom
=
"/docProps/custom.xml"
;
$self
->_add_override(
$custom
,
$app_document
.
'custom-properties+xml'
);
}
###############################################################################
#
# _add_metadata()
#
# Add the metadata file to the ContentTypes overrides.
#
sub
_add_metadata {
my
$self
=
shift
;
my
$custom
=
"/xl/metadata.xml"
;
$self
->_add_override(
$custom
,
$app_document
.
'spreadsheetml.sheetMetadata+xml'
);
}
###############################################################################
#
# _add_richvalue()
#
# Add the RichValue files to the ContentTypes overrides.
#
sub
_add_richvalue {
my
$self
=
shift
;
$self
->_add_override(
'/xl/richData/rdRichValueTypes.xml'
,
'application/vnd.ms-excel.rdrichvaluetypes+xml'
);
$self
->_add_override(
'/xl/richData/rdrichvalue.xml'
,
'application/vnd.ms-excel.rdrichvalue+xml'
);
$self
->_add_override(
'/xl/richData/rdrichvaluestructure.xml'
,
'application/vnd.ms-excel.rdrichvaluestructure+xml'
);
$self
->_add_override(
'/xl/richData/richValueRel.xml'
,
'application/vnd.ms-excel.richvaluerel+xml'
);
}
###############################################################################
#
# Internal methods.
#
###############################################################################
###############################################################################
#
# _write_defaults()
#
# Write out all of the <Default> types.
#
sub
_write_defaults {
my
$self
=
shift
;
for
my
$aref
( @{
$self
->{_defaults} } ) {
#<<<
$self
->xml_empty_tag(
'Default'
,
'Extension'
,
$aref
->[0],
'ContentType'
,
$aref
->[1] );
#>>>
}
}
###############################################################################
#
# _write_overrides()
#
# Write out all of the <Override> types.
#
sub
_write_overrides {
my
$self
=
shift
;
for
my
$aref
( @{
$self
->{_overrides} } ) {
#<<<
$self
->xml_empty_tag(
'Override'
,
'PartName'
,
$aref
->[0],
'ContentType'
,
$aref
->[1] );
#>>>
}
}
###############################################################################
#
# XML writing methods.
#
###############################################################################
###############################################################################
#
# _write_types()
#
# Write the <Types> element.
#
sub
_write_types {
my
$self
=
shift
;
my
@attributes
= (
'xmlns'
=>
$xmlns
, );
$self
->xml_start_tag(
'Types'
,
@attributes
);
}
###############################################################################
#
# _write_default()
#
# Write the <Default> element.
#
sub
_write_default {
my
$self
=
shift
;
my
$extension
=
shift
;
my
$content_type
=
shift
;
my
@attributes
= (
'Extension'
=>
$extension
,
'ContentType'
=>
$content_type
,
);
$self
->xml_empty_tag(
'Default'
,
@attributes
);
}
###############################################################################
#
# _write_override()
#
# Write the <Override> element.
#
sub
_write_override {
my
$self
=
shift
;
my
$part_name
=
shift
;
my
$content_type
=
shift
;
my
$writer
=
$self
;
my
@attributes
= (
'PartName'
=>
$part_name
,
'ContentType'
=>
$content_type
,
);
$self
->xml_empty_tag(
'Override'
,
@attributes
);
}
1;
__END__
=pod
=head1 NAME
Excel::Writer::XLSX::Package::ContentTypes - A class for writing the Excel XLSX [Content_Types] file.
=head1 SYNOPSIS
See the documentation for L<Excel::Writer::XLSX>.
=head1 DESCRIPTION
This module is used in conjunction with L<Excel::Writer::XLSX>.
=head1 AUTHOR
John McNamara jmcnamara@cpan.org
=head1 COPYRIGHT
(c) MM-MMXXIV, John McNamara.
All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.
=head1 LICENSE
Either the Perl Artistic Licence L<https://dev.perl.org/licenses/artistic.html> or the GNU General Public License v1.0 or later L<https://dev.perl.org/licenses/gpl1.html>.
=head1 DISCLAIMER OF WARRANTY
See the documentation for L<Excel::Writer::XLSX>.
=cut