diff --git a/src/Spout/Writer/WriterAbstract.php b/src/Spout/Writer/WriterAbstract.php index bbaa735..93f9891 100644 --- a/src/Spout/Writer/WriterAbstract.php +++ b/src/Spout/Writer/WriterAbstract.php @@ -112,7 +112,7 @@ abstract class WriterAbstract implements WriterInterface * @codeCoverageIgnore * {@inheritdoc} */ - public function openToBrowser($outputFileName) + public function openToBrowser($outputFileName, array $headers = []) { $this->outputFilePath = $this->globalFunctionsHelper->basename($outputFileName); @@ -123,9 +123,26 @@ abstract class WriterAbstract implements WriterInterface // @see https://github.com/box/spout/issues/241 $this->globalFunctionsHelper->ob_end_clean(); - // Set headers + /* + * Set headers + * + * For newer browsers such as Firefox, Chrome, Opera, Safari, etc., they all support and use `filename*` + * specified by the new standard, even if they do not automatically decode filename; it does not matter; + * and for older versions of Internet Explorer, they are not recognized `filename*`, will automatically + * ignore it and use the old `filename` (the only minor flaw is that there must be an English suffix name). + * In this way, the multi-browser multi-language compatibility problem is perfectly solved, which does not + * require UA judgment and is more in line with the standard. + * + * @see https://github.com/box/spout/issues/745 + * @see https://tools.ietf.org/html/rfc6266 + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition + */ $this->globalFunctionsHelper->header('Content-Type: ' . static::$headerContentType); - $this->globalFunctionsHelper->header('Content-Disposition: attachment; filename="' . $this->outputFilePath . '"'); + $this->globalFunctionsHelper->header( + 'Content-Disposition: attachment; ' . + 'filename="' . rawurldecode($this->outputFilePath) . '"; ' . + 'filename*=UTF-8\'\'' . rawurldecode($this->outputFilePath) + ); /* * When forcing the download of a file over SSL,IE8 and lower browsers fail @@ -137,6 +154,16 @@ abstract class WriterAbstract implements WriterInterface $this->globalFunctionsHelper->header('Cache-Control: max-age=0'); $this->globalFunctionsHelper->header('Pragma: public'); + /* + * Set custom Headers + * Sometimes need to output or cover more headers. + * + * @see https://github.com/box/spout/issues/745 + */ + foreach ($headers as $header){ + $this->globalFunctionsHelper->header($header); + } + $this->openWriter(); $this->isWriterOpened = true;