-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[IMP] xlsx_import: support more date formats
We now try to parse and modify the xlsx date formats at import to get a format supported by o_spreadsheet. Odoo task 3222986 closes #2293 Signed-off-by: Lucas Lefèvre (lul) <[email protected]>
- Loading branch information
1 parent
3792988
commit c712b02
Showing
20 changed files
with
703 additions
and
958 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { formatValue } from "../../helpers"; | ||
import { XLSXNumFormat } from "../../types/xlsx"; | ||
import { WarningTypes, XLSXImportWarningManager } from "../helpers/xlsx_parser_error_manager"; | ||
import { XLSX_FORMATS_CONVERSION_MAP } from "./conversion_maps"; | ||
|
||
const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/m|\s|-|\/|\.|:)+$/i; | ||
|
||
/** | ||
* Convert excel format to o_spreadsheet format | ||
* | ||
* Excel format are defined in openXML §18.8.31 | ||
*/ | ||
export function convertXlsxFormat( | ||
numFmtId: number, | ||
formats: XLSXNumFormat[], | ||
warningManager: XLSXImportWarningManager | ||
): string | undefined { | ||
if (numFmtId === 0) { | ||
return undefined; | ||
} | ||
// Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30 | ||
let format = | ||
XLSX_FORMATS_CONVERSION_MAP[numFmtId] || formats.find((f) => f.id === numFmtId)?.format; | ||
|
||
if (format) { | ||
try { | ||
let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format | ||
convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31) | ||
convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks | ||
|
||
// Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format | ||
const numberOfQuotes = convertedFormat.match(/"/g)?.length || 0; | ||
const numberOfOpenBrackets = convertedFormat.match(/\[/g)?.length || 0; | ||
if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) { | ||
throw new Error("Multiple escaped blocks in format"); | ||
} | ||
convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]' | ||
|
||
convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore width of next char for align purposes. Not supported ATM | ||
convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM | ||
|
||
convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces | ||
|
||
convertedFormat = convertedFormat.replace(/\\./g, (match) => match[1]); // unescape other characters | ||
|
||
if (isXlsxDateFormat(convertedFormat)) { | ||
convertedFormat = convertDateFormat(convertedFormat); | ||
} | ||
|
||
if (isFormatSupported(convertedFormat)) { | ||
return convertedFormat; | ||
} | ||
} catch (e) {} | ||
} | ||
|
||
warningManager.generateNotSupportedWarning( | ||
WarningTypes.NumFmtIdNotSupported, | ||
format || `nmFmtId ${numFmtId}` | ||
); | ||
return undefined; | ||
} | ||
|
||
function isFormatSupported(format: string): boolean { | ||
try { | ||
formatValue(0, format); | ||
return true; | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
|
||
function isXlsxDateFormat(format: string): boolean { | ||
return format.match(XLSX_DATE_FORMAT_REGEX) !== null; | ||
} | ||
|
||
function convertDateFormat(format: string): string { | ||
// Some of these aren't defined neither in the OpenXML spec not the Xlsx extension of OpenXML, | ||
// but can still occur and are supported by Excel/Google sheets | ||
|
||
format = format.toLowerCase(); | ||
format = format.replace(/mmmmm/g, "mmm"); | ||
format = format.replace(/am\/pm|a\/m/g, "a"); | ||
format = format.replace(/hhhh/g, "hh"); | ||
format = format.replace(/\bh\b/g, "hh"); | ||
|
||
return format; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.