UNPKG

devexpress-richedit

Version:

DevExpress Rich Text Editor is an advanced word-processing tool designed for working with rich text documents.

147 lines (146 loc) 9.31 kB
import { DocumentImporterErrors } from '../../../../common/formats/document-importer-errors'; import { SectionRestorer } from '../../../../common/formats/model-restorer/section-restorer'; import { TableRestorer } from '../../../../common/formats/model-restorer/table-restorer'; import { ModelCreator } from '../../../../common/model/creator/creator'; import { ModelCreatorOptions } from '../../../../common/model/creator/options'; import { CompatibilityMode } from '../../../../common/model/document-model'; import { ModelChecker } from '../../../../common/model/model-checks/check-all'; import { ListUtils } from '@devexpress/utils/lib/utils/list'; import { StringMapUtils } from '@devexpress/utils/lib/utils/map/string'; import { PathHelper } from '../utils/path-helper'; import { ArchiveData } from '../zip/zip-reader'; import { Data } from './data'; import { DocumentDestination } from './destination/document/document-destination'; import { NumberingsDestination } from './destination/numbering/numberings-destination'; import { DocumentSettingsDestination } from './destination/settings/settings'; import { StylesDestination } from './destination/style/styles-destination'; import { OfficeThemeDestination } from './destination/themes/office-theme-destination'; import { FootNotesDestination } from './destination/notes/footnotes/footnotes-destination'; import { EndNotesDestination } from './destination/notes/endnotes/endnotes-destination'; export class Importer { data; callback; options; asyncImportFromFile = true; reject; constructor(options) { this.options = options; } async importFromFile(blob, modelOptions, callback, reject) { this.reject = reject; this.callback = callback; const modelCreatorOptions = new ModelCreatorOptions(); modelCreatorOptions.addParagraph = false; modelCreatorOptions.addSection = false; try { const archiveData = new ArchiveData(this.options); await archiveData.init(blob); this.data = new Data(this.options, archiveData, new ModelCreator(modelCreatorOptions).createModel(modelOptions).fillModel()); if (!blob.size) throw new Error("Empty file"); await this.importRootRelations(); await this.importMainSubDocument(); TableRestorer.paragraphMarkBetween(this.data.documentModel); TableRestorer.fixAllTables(this.data.documentModel); SectionRestorer.fixLastSection(this.data.documentModel); TableRestorer.fixLastParagraphs(this.data.documentModel); if (!new ModelChecker(this.data.documentModel).checkAll()) throw new Error(); } catch (err) { this.reject(DocumentImporterErrors.OpenXmlImportError); return; } this.callback(this.data.documentModel, this.data.formatImagesImporter); } async importRootRelations() { return this.data.addRelations('_rels/.rels'); } async importMainSubDocument() { const documentFileName = this.data.relationsStack.last.lookupRelationTargetByType(this.data.constants.rels.officeDocumentType, '', 'document.xml'); this.data.documentRootFolder = PathHelper.getDir(documentFileName); await this.data.addRelations(`${this.data.documentRootFolder}/_rels/${PathHelper.getFileName(documentFileName)}.rels`); await this.importSettings(); await this.importThemes(); await this.importNumbering(); await this.importStyles(); await this.importFootNotes(); await this.importEndNotes(); this.linkNumberingListStyles(); const documentReader = await this.data.archiveData.getXmlReader(documentFileName); if (documentReader.readToFollowingNS('document', this.data.constants.wordProcessingNamespaceConst)) { await this.data.importContent(documentReader, new DocumentDestination(this.data)); this.data.sectionImporter.finishSection(); this.data.popCurrentSubDocument(); } else { this.data.options.throwInvalidFile('Not found document element'); } this.data.relationsStack.pop(); } async importStyles() { const styleFileName = this.data.relationsStack.last.lookupRelationTargetByType(this.data.constants.rels.officeStylesType, this.data.documentRootFolder, 'styles.xml'); const stylesReader = await this.data.archiveData.getXmlReader(styleFileName); if (stylesReader && stylesReader.readToFollowingNS('styles', this.data.constants.wordProcessingNamespaceConst)) { this.data.stylesImporter.presetDefaultStyles(); await this.data.importContent(stylesReader, new StylesDestination(this.data)); this.data.stylesImporter.determineParents(); this.data.stylesImporter.linkStyles(); } else { this.data.options.throwInvalidFile('Not found style element'); } } async importFootNotes() { const footNotesFileName = 'footnotes.xml'; const footNotesFilePath = this.data.relationsStack.last.lookupRelationTargetByType(this.data.constants.rels.officeFootNoteType, this.data.documentRootFolder, footNotesFileName); await this.data.addRelations(`${this.data.documentRootFolder}/_rels/${footNotesFileName}.rels`); const footNotesReader = await this.data.archiveData.getXmlReader(footNotesFilePath); if (footNotesReader && footNotesReader.readToFollowingNS('footnotes', this.data.constants.wordProcessingNamespaceConst)) await this.data.importContent(footNotesReader, new FootNotesDestination(this.data)); this.data.relationsStack.pop(); } async importEndNotes() { const endNotesFileName = 'endnotes.xml'; const endNotesFilePath = this.data.relationsStack.last.lookupRelationTargetByType(this.data.constants.rels.officeEndNoteType, this.data.documentRootFolder, endNotesFileName); await this.data.addRelations(`${this.data.documentRootFolder}/_rels/${endNotesFileName}.rels`); const endNotesReader = await this.data.archiveData.getXmlReader(endNotesFilePath); if (endNotesReader && endNotesReader.readToFollowingNS('endnotes', this.data.constants.wordProcessingNamespaceConst)) await this.data.importContent(endNotesReader, new EndNotesDestination(this.data)); this.data.relationsStack.pop(); } async importThemes() { const themeFileName = this.data.relationsStack.last.lookupRelationTargetByType(this.data.constants.rels.officeThemesType, this.data.documentRootFolder, 'theme/theme1.xml'); await this.data.addRelations(`${this.data.documentRootFolder}/_rels/theme/theme1.xml.rels`); const themesReader = await this.data.archiveData.getXmlReader(themeFileName); if (themesReader && themesReader.readToFollowingNS('theme', this.data.constants.drawingMLNamespaceConst)) await this.data.importContent(themesReader, new OfficeThemeDestination(this.data)); this.data.relationsStack.pop(); } async importNumbering() { const numberingFileName = this.data.relationsStack.last.lookupRelationTargetByType(this.data.constants.rels.officeNumberingType, this.data.documentRootFolder, 'numbering.xml'); const numberingReader = await this.data.archiveData.getXmlReader(numberingFileName); if (numberingReader && numberingReader.readToFollowingNS('numbering', this.data.constants.wordProcessingNamespaceConst)) await this.data.importContent(numberingReader, new NumberingsDestination(this.data)); this.data.stylesImporter.createNumberingLists(this.data.documentModel); } async importSettings() { this.data.documentModel.compatibilitySettings.compatibilityMode = CompatibilityMode.Word2007; const fileName = this.data.relationsStack.last.lookupRelationTargetByType(this.data.constants.rels.officeDocumentSettings, this.data.documentRootFolder, 'settings.xml'); const reader = await this.data.archiveData.getXmlReader(fileName); if (reader && reader.readToFollowingNS('settings', this.data.constants.wordProcessingNamespaceConst)) await this.data.importContent(reader, new DocumentSettingsDestination(this.data)); } linkNumberingListStyles() { StringMapUtils.forEach(this.data.stylesImporter.abstractListInfos, (info) => { if (info.numberingStyleReferenceIndex != null) { const abstractNumList = this.data.documentModel.abstractNumberingLists[info.abstractNumberingIndex]; const style = this.data.stylesImporter.numberingListManager.getStyleById(info.numberingStyleReferenceIndex); const abstractRefNumList = this.data.documentModel.abstractNumberingLists[this.data.documentModel.numberingLists[style.numberingListIndex].abstractNumberingListIndex]; ListUtils.forEach(abstractNumList.levels, (level, index) => { level.copyFrom(abstractRefNumList.levels[index]); }); } }); } }