java 项目整合ckeditor实现图文混排
来源:互联网 发布:后三胆码计算软件 编辑:程序博客网 时间:2024/06/10 14:14
首先从官网下载ckeditor包(http://ckeditor.com/download)。这里根据需要不同的版本,因为我做的功能是实现图片和文字显示,很简单的功能,所以选择的是standard package。将ckeditor包放在webapp下。
在html中使用textarea 标签加载插件
<script src="../../ckeditor/ckeditor.js"></script>
<textarea class="easyui-validatebox" name="newsMatter" id="newsMatter" rows="20" cols="70" data-options="required:true"> </textarea>
然后在js文件中加载ckeditor
CKEDITOR.replace('newsMatter', { height : 300, filebrowserImageUploadUrl : baseurl + "/imageUpload.do" });
js中获取textarea 中的值:
$('#newsMatter').each(function () { var $textarea = $(this); var data=CKEDITOR.instances[$textarea.attr('name')].getData(); data=data.replace(/“/g,'\"');//转义“ 左双引号 data=data.replace(/”/g,'\"');//转义“ 右双引号 $textarea.val(data); });
这里的filebrowserImageUploadUrl 是文件上传的路径,有值才会显示上传卡片。
这里是maven项目,所以直接在pom.xml中使用依赖
<dependency> <groupId>com.ckeditor</groupId> <artifactId>ckeditor-java-core</artifactId> <version>3.5.3</version></dependency>
至此,环境大体是搭建完成。但是做成想要的样子还需要修改js文件。
ckeditor/config.js中配置如下:
CKEDITOR.editorConfig = function( config ) { // Define changes to default configuration here. // For complete reference see: // http://docs.ckeditor.com/#!/api/CKEDITOR.config // The toolbar groups arrangement, optimized for two toolbar rows./* config.toolbarGroups = [ { name: 'clipboard', groups: [ 'clipboard', 'undo' ] }, { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] }, { name: 'links' }, { name: 'insert' }, { name: 'forms' }, { name: 'tools' }, { name: 'document', groups: [ 'mode', 'document', 'doctools' ] }, { name: 'others' }, '/', { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] }, { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] }, { name: 'styles' }, { name: 'colors' }, { name: 'about' } ];*/ config.toolbar=[ {name:'insert',items:['Image']} ]; // Remove some buttons provided by the standard plugins, which are // not needed in the Standard(s) toolbar. // Set the most common block elements. config.format_tags = 'p;h1;h2;h3;pre'; // Simplify the dialog windows. config.removeDialogTabs = 'image:advanced;link:advanced';// config.filebrowserImageUploadUrl = 'upload.do?type=Image'; config.enterMode = CKEDITOR.ENTER_BR; config.shiftEnterMode = CKEDITOR.ENTER_P; };
ckeditor/plugins/image/dialogs/image.js文件如下:
/*Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.For licensing, see LICENSE.html or http://ckeditor.com/license*/(function(){ var imageDialog = function( editor, dialogType ) { // Load image preview. var IMAGE = 1, LINK = 2, PREVIEW = 4, CLEANUP = 8, regexGetSize = /^\s*(\d+)((px)|\%)?\s*$/i, regexGetSizeOrEmpty = /(^\s*(\d+)((px)|\%)?\s*$)|^$/i, pxLengthRegex = /^\d+px$/; var onSizeChange = function() { var value = this.getValue(), // This = input element. dialog = this.getDialog(), aMatch = value.match( regexGetSize ); // Check value if ( aMatch ) { if ( aMatch[2] == '%' ) // % is allowed - > unlock ratio. switchLockRatio( dialog, false ); // Unlock. value = aMatch[1]; } // Only if ratio is locked if ( dialog.lockRatio ) { var oImageOriginal = dialog.originalElement; if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' ) { if ( this.id == 'txtHeight' ) { if ( value && value != '0' ) value = Math.round( oImageOriginal.$.width * ( value / oImageOriginal.$.height ) ); if ( !isNaN( value ) ) dialog.setValueOf( 'info', 'txtWidth', value ); } else //this.id = txtWidth. { if ( value && value != '0' ) value = Math.round( oImageOriginal.$.height * ( value / oImageOriginal.$.width ) ); if ( !isNaN( value ) ) dialog.setValueOf( 'info', 'txtHeight', value ); } } } updatePreview( dialog ); }; var updatePreview = function( dialog ) { //Don't load before onShow. if ( !dialog.originalElement || !dialog.preview ) return 1; // Read attributes and update imagePreview; dialog.commitContent( PREVIEW, dialog.preview ); return 0; }; // Custom commit dialog logic, where we're intended to give inline style // field (txtdlgGenStyle) higher priority to avoid overwriting styles contribute // by other fields. function commitContent() { var args = arguments; var inlineStyleField = this.getContentElement( 'advanced', 'txtdlgGenStyle' ); inlineStyleField && inlineStyleField.commit.apply( inlineStyleField, args ); this.foreach( function( widget ) { if ( widget.commit && widget.id != 'txtdlgGenStyle' ) widget.commit.apply( widget, args ); }); } // Avoid recursions. var incommit; // Synchronous field values to other impacted fields is required, e.g. border // size change should alter inline-style text as well. function commitInternally( targetFields ) { if ( incommit ) return; incommit = 1; var dialog = this.getDialog(), element = dialog.imageElement; if ( element ) { // Commit this field and broadcast to target fields. this.commit( IMAGE, element ); targetFields = [].concat( targetFields ); var length = targetFields.length, field; for ( var i = 0; i < length; i++ ) { field = dialog.getContentElement.apply( dialog, targetFields[ i ].split( ':' ) ); // May cause recursion. field && field.setup( IMAGE, element ); } } incommit = 0; } var switchLockRatio = function( dialog, value ) { if ( !dialog.getContentElement( 'info', 'ratioLock' ) ) return null; var oImageOriginal = dialog.originalElement; // Dialog may already closed. (#5505) if( !oImageOriginal ) return null; // Check image ratio and original image ratio, but respecting user's preference. if ( value == 'check' ) { if ( !dialog.userlockRatio && oImageOriginal.getCustomData( 'isReady' ) == 'true' ) { var width = dialog.getValueOf( 'info', 'txtWidth' ), height = dialog.getValueOf( 'info', 'txtHeight' ), originalRatio = oImageOriginal.$.width * 1000 / oImageOriginal.$.height, thisRatio = width * 1000 / height; dialog.lockRatio = false; // Default: unlock ratio if ( !width && !height ) dialog.lockRatio = true; else if ( !isNaN( originalRatio ) && !isNaN( thisRatio ) ) { if ( Math.round( originalRatio ) == Math.round( thisRatio ) ) dialog.lockRatio = true; } } } else if ( value != undefined ) dialog.lockRatio = value; else { dialog.userlockRatio = 1; dialog.lockRatio = !dialog.lockRatio; } var ratioButton = CKEDITOR.document.getById( btnLockSizesId ); if ( dialog.lockRatio ) ratioButton.removeClass( 'cke_btn_unlocked' ); else ratioButton.addClass( 'cke_btn_unlocked' ); ratioButton.setAttribute( 'aria-checked', dialog.lockRatio ); // Ratio button hc presentation - WHITE SQUARE / BLACK SQUARE if ( CKEDITOR.env.hc ) { var icon = ratioButton.getChild( 0 ); icon.setHtml( dialog.lockRatio ? CKEDITOR.env.ie ? '\u25A0': '\u25A3' : CKEDITOR.env.ie ? '\u25A1' : '\u25A2' ); } return dialog.lockRatio; }; var resetSize = function( dialog ) { var oImageOriginal = dialog.originalElement; if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' ) { var widthField = dialog.getContentElement( 'info', 'txtWidth' ), heightField = dialog.getContentElement( 'info', 'txtHeight' ); widthField && widthField.setValue( oImageOriginal.$.width ); heightField && heightField.setValue( oImageOriginal.$.height ); } updatePreview( dialog ); }; var setupDimension = function( type, element ) { if ( type != IMAGE ) return; function checkDimension( size, defaultValue ) { var aMatch = size.match( regexGetSize ); if ( aMatch ) { if ( aMatch[2] == '%' ) // % is allowed. { aMatch[1] += '%'; switchLockRatio( dialog, false ); // Unlock ratio } return aMatch[1]; } return defaultValue; } var dialog = this.getDialog(), value = '', dimension = this.id == 'txtWidth' ? 'width' : 'height', size = element.getAttribute( dimension ); if ( size ) value = checkDimension( size, value ); value = checkDimension( element.getStyle( dimension ), value ); this.setValue( value ); }; var previewPreloader; var onImgLoadEvent = function() { // Image is ready. var original = this.originalElement; original.setCustomData( 'isReady', 'true' ); original.removeListener( 'load', onImgLoadEvent ); original.removeListener( 'error', onImgLoadErrorEvent ); original.removeListener( 'abort', onImgLoadErrorEvent ); // Hide loader CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' ); // New image -> new domensions if ( !this.dontResetSize ) resetSize( this ); if ( this.firstLoad ) CKEDITOR.tools.setTimeout( function(){ switchLockRatio( this, 'check' ); }, 0, this ); this.firstLoad = false; this.dontResetSize = false; }; var onImgLoadErrorEvent = function() { // Error. Image is not loaded. var original = this.originalElement; original.removeListener( 'load', onImgLoadEvent ); original.removeListener( 'error', onImgLoadErrorEvent ); original.removeListener( 'abort', onImgLoadErrorEvent ); // Set Error image. var noimage = CKEDITOR.getUrl( editor.skinPath + 'images/noimage.png' ); if ( this.preview ) this.preview.setAttribute( 'src', noimage ); // Hide loader CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' ); switchLockRatio( this, false ); // Unlock. }; var numbering = function( id ) { return CKEDITOR.tools.getNextId() + '_' + id; }, btnLockSizesId = numbering( 'btnLockSizes' ), btnResetSizeId = numbering( 'btnResetSize' ), imagePreviewLoaderId = numbering( 'ImagePreviewLoader' ), previewLinkId = numbering( 'previewLink' ), previewImageId = numbering( 'previewImage' ); return { title : editor.lang.image[ dialogType == 'image' ? 'title' : 'titleButton' ], minWidth : 420, minHeight : 360, onShow : function() { this.imageElement = false; this.linkElement = false; // Default: create a new element. this.imageEditMode = false; this.linkEditMode = false; this.lockRatio = true; this.userlockRatio = 0; this.dontResetSize = false; this.firstLoad = true; this.addLink = false; var editor = this.getParentEditor(), sel = editor.getSelection(), element = sel && sel.getSelectedElement(), link = element && element.getAscendant( 'a' ); //Hide loader. CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' ); // Create the preview before setup the dialog contents. previewPreloader = new CKEDITOR.dom.element( 'img', editor.document ); this.preview = CKEDITOR.document.getById( previewImageId ); // Copy of the image this.originalElement = editor.document.createElement( 'img' ); this.originalElement.setAttribute( 'alt', '' ); this.originalElement.setCustomData( 'isReady', 'false' ); if ( link ) { this.linkElement = link; this.linkEditMode = true; // Look for Image element. var linkChildren = link.getChildren(); if ( linkChildren.count() == 1 ) // 1 child. { var childTagName = linkChildren.getItem( 0 ).getName(); if ( childTagName == 'img' || childTagName == 'input' ) { this.imageElement = linkChildren.getItem( 0 ); if ( this.imageElement.getName() == 'img' ) this.imageEditMode = 'img'; else if ( this.imageElement.getName() == 'input' ) this.imageEditMode = 'input'; } } // Fill out all fields. if ( dialogType == 'image' ) this.setupContent( LINK, link ); } if ( element && element.getName() == 'img' && !element.data( 'cke-realelement' ) || element && element.getName() == 'input' && element.getAttribute( 'type' ) == 'image' ) { this.imageEditMode = element.getName(); this.imageElement = element; } if ( this.imageEditMode ) { // Use the original element as a buffer from since we don't want // temporary changes to be committed, e.g. if the dialog is canceled. this.cleanImageElement = this.imageElement; this.imageElement = this.cleanImageElement.clone( true, true ); // Fill out all fields. this.setupContent( IMAGE, this.imageElement ); } else this.imageElement = editor.document.createElement( 'img' ); // Refresh LockRatio button switchLockRatio ( this, true ); // Dont show preview if no URL given. if ( !CKEDITOR.tools.trim( this.getValueOf( 'info', 'txtUrl' ) ) ) { this.preview.removeAttribute( 'src' ); this.preview.setStyle( 'display', 'none' ); } }, onOk : function() { // Edit existing Image. if ( this.imageEditMode ) { var imgTagName = this.imageEditMode; // Image dialog and Input element. if ( dialogType == 'image' && imgTagName == 'input' && confirm( editor.lang.image.button2Img ) ) { // Replace INPUT-> IMG imgTagName = 'img'; this.imageElement = editor.document.createElement( 'img' ); this.imageElement.setAttribute( 'alt', '' ); editor.insertElement( this.imageElement ); } // ImageButton dialog and Image element. else if ( dialogType != 'image' && imgTagName == 'img' && confirm( editor.lang.image.img2Button )) { // Replace IMG -> INPUT imgTagName = 'input'; this.imageElement = editor.document.createElement( 'input' ); this.imageElement.setAttributes( { type : 'image', alt : '' } ); editor.insertElement( this.imageElement ); } else { // Restore the original element before all commits. this.imageElement = this.cleanImageElement; delete this.cleanImageElement; } } else // Create a new image. { // Image dialog -> create IMG element. if ( dialogType == 'image' ) this.imageElement = editor.document.createElement( 'img' ); else { this.imageElement = editor.document.createElement( 'input' ); this.imageElement.setAttribute ( 'type' ,'image' ); } this.imageElement.setAttribute( 'alt', '' ); } // Create a new link. if ( !this.linkEditMode ) this.linkElement = editor.document.createElement( 'a' ); // Set attributes. this.commitContent( IMAGE, this.imageElement ); this.commitContent( LINK, this.linkElement ); // Remove empty style attribute. if ( !this.imageElement.getAttribute( 'style' ) ) this.imageElement.removeAttribute( 'style' ); // Insert a new Image. if ( !this.imageEditMode ) { if ( this.addLink ) { //Insert a new Link. if ( !this.linkEditMode ) { editor.insertElement( this.linkElement ); this.linkElement.append( this.imageElement, false ); } else //Link already exists, image not. editor.insertElement( this.imageElement ); } else editor.insertElement( this.imageElement ); } else // Image already exists. { //Add a new link element. if ( !this.linkEditMode && this.addLink ) { editor.insertElement( this.linkElement ); this.imageElement.appendTo( this.linkElement ); } //Remove Link, Image exists. else if ( this.linkEditMode && !this.addLink ) { editor.getSelection().selectElement( this.linkElement ); editor.insertElement( this.imageElement ); } } }, onLoad : function() { if ( dialogType != 'image' ) this.hidePage( 'Link' ); //Hide Link tab. var doc = this._.element.getDocument(); if ( this.getContentElement( 'info', 'ratioLock' ) ) { this.addFocusable( doc.getById( btnResetSizeId ), 5 ); this.addFocusable( doc.getById( btnLockSizesId ), 5 ); } this.commitContent = commitContent; }, onHide : function() { if ( this.preview ) this.commitContent( CLEANUP, this.preview ); if ( this.originalElement ) { this.originalElement.removeListener( 'load', onImgLoadEvent ); this.originalElement.removeListener( 'error', onImgLoadErrorEvent ); this.originalElement.removeListener( 'abort', onImgLoadErrorEvent ); this.originalElement.remove(); this.originalElement = false; // Dialog is closed. } delete this.imageElement; }, contents : [ { id : 'info', label : editor.lang.image.infoTab, accessKey : 'I', elements : [ { type : 'vbox', padding : 0, children : [ { type : 'hbox', widths : [ '280px', '110px' ], align : 'right', children : [ { id : 'txtUrl', type : 'text', label : editor.lang.common.url, required: true, onChange : function() { var dialog = this.getDialog(), newUrl = this.getValue(); //Update original image if ( newUrl.length > 0 ) //Prevent from load before onShow { dialog = this.getDialog(); var original = dialog.originalElement; dialog.preview.removeStyle( 'display' ); original.setCustomData( 'isReady', 'false' ); // Show loader var loader = CKEDITOR.document.getById( imagePreviewLoaderId ); if ( loader ) loader.setStyle( 'display', '' ); original.on( 'load', onImgLoadEvent, dialog ); original.on( 'error', onImgLoadErrorEvent, dialog ); original.on( 'abort', onImgLoadErrorEvent, dialog ); original.setAttribute( 'src', newUrl ); // Query the preloader to figure out the url impacted by based href. previewPreloader.setAttribute( 'src', newUrl ); dialog.preview.setAttribute( 'src', previewPreloader.$.src ); updatePreview( dialog ); } // Dont show preview if no URL given. else if ( dialog.preview ) { dialog.preview.removeAttribute( 'src' ); dialog.preview.setStyle( 'display', 'none' ); } }, setup : function( type, element ) { if ( type == IMAGE ) { var url = element.data( 'cke-saved-src' ) || element.getAttribute( 'src' ); var field = this; this.getDialog().dontResetSize = true; field.setValue( url ); // And call this.onChange() // Manually set the initial value.(#4191) field.setInitValue(); } }, commit : function( type, element ) { if ( type == IMAGE && ( this.getValue() || this.isChanged() ) ) { element.data( 'cke-saved-src', this.getValue() ); element.setAttribute( 'src', this.getValue() ); } else if ( type == CLEANUP ) { element.setAttribute( 'src', '' ); // If removeAttribute doesn't work. element.removeAttribute( 'src' ); } }, validate : CKEDITOR.dialog.validate.notEmpty( editor.lang.image.urlMissing ) }, { type : 'button', id : 'browse', // v-align with the 'txtUrl' field. // TODO: We need something better than a fixed size here. style : 'display:inline-block;margin-top:10px;', align : 'center', label : editor.lang.common.browseServer, hidden : false, filebrowser : 'info:txtUrl' } ] } ] }, { id : 'txtAlt', type : 'text', label : editor.lang.image.alt, accessKey : 'T', 'default' : '', onChange : function() { updatePreview( this.getDialog() ); }, setup : function( type, element ) { if ( type == IMAGE ) this.setValue( element.getAttribute( 'alt' ) ); }, commit : function( type, element ) { if ( type == IMAGE ) { if ( this.getValue() || this.isChanged() ) element.setAttribute( 'alt', this.getValue() ); } else if ( type == PREVIEW ) { element.setAttribute( 'alt', this.getValue() ); } else if ( type == CLEANUP ) { element.removeAttribute( 'alt' ); } } }, { type : 'hbox', children : [ { id : 'basic', type : 'vbox', children : [ { type : 'hbox', widths : [ '50%', '50%' ], children : [ { type : 'vbox', padding : 1, children : [ { type : 'text', width: '50px', id : 'txtWidth', label : editor.lang.common.width, onKeyUp : onSizeChange, onChange : function() { commitInternally.call( this, 'advanced:txtdlgGenStyle' ); }, validate : function() { var aMatch = this.getValue().match( regexGetSizeOrEmpty ), isValid = !!( aMatch && parseInt( aMatch[1], 10 ) !== 0 ); if ( !isValid ) alert( editor.lang.common.invalidWidth ); return isValid; }, setup : setupDimension, commit : function( type, element, internalCommit ) { var value = this.getValue(); if ( type == IMAGE ) { if ( value ) element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) ); else element.removeStyle( 'width' ); !internalCommit && element.removeAttribute( 'width' ); } else if ( type == PREVIEW ) { var aMatch = value.match( regexGetSize ); if ( !aMatch ) { var oImageOriginal = this.getDialog().originalElement; if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' ) element.setStyle( 'width', oImageOriginal.$.width + 'px'); } else element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) ); } else if ( type == CLEANUP ) { element.removeAttribute( 'width' ); element.removeStyle( 'width' ); } } }, { type : 'text', id : 'txtHeight', width: '50px', label : editor.lang.common.height, onKeyUp : onSizeChange, onChange : function() { commitInternally.call( this, 'advanced:txtdlgGenStyle' ); }, validate : function() { var aMatch = this.getValue().match( regexGetSizeOrEmpty ), isValid = !!( aMatch && parseInt( aMatch[1], 10 ) !== 0 ); if ( !isValid ) alert( editor.lang.common.invalidHeight ); return isValid; }, setup : setupDimension, commit : function( type, element, internalCommit ) { var value = this.getValue(); if ( type == IMAGE ) { if ( value ) element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) ); else element.removeStyle( 'height' ); !internalCommit && element.removeAttribute( 'height' ); } else if ( type == PREVIEW ) { var aMatch = value.match( regexGetSize ); if ( !aMatch ) { var oImageOriginal = this.getDialog().originalElement; if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' ) element.setStyle( 'height', oImageOriginal.$.height + 'px' ); } else element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) ); } else if ( type == CLEANUP ) { element.removeAttribute( 'height' ); element.removeStyle( 'height' ); } } } ] }, { id : 'ratioLock', type : 'html', style : 'margin-top:30px;width:40px;height:40px;', onLoad : function() { // Activate Reset button var resetButton = CKEDITOR.document.getById( btnResetSizeId ), ratioButton = CKEDITOR.document.getById( btnLockSizesId ); if ( resetButton ) { resetButton.on( 'click', function( evt ) { resetSize( this ); evt.data && evt.data.preventDefault(); }, this.getDialog() ); resetButton.on( 'mouseover', function() { this.addClass( 'cke_btn_over' ); }, resetButton ); resetButton.on( 'mouseout', function() { this.removeClass( 'cke_btn_over' ); }, resetButton ); } // Activate (Un)LockRatio button if ( ratioButton ) { ratioButton.on( 'click', function(evt) { var locked = switchLockRatio( this ), oImageOriginal = this.originalElement, width = this.getValueOf( 'info', 'txtWidth' ); if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' && width ) { var height = oImageOriginal.$.height / oImageOriginal.$.width * width; if ( !isNaN( height ) ) { this.setValueOf( 'info', 'txtHeight', Math.round( height ) ); updatePreview( this ); } } evt.data && evt.data.preventDefault(); }, this.getDialog() ); ratioButton.on( 'mouseover', function() { this.addClass( 'cke_btn_over' ); }, ratioButton ); ratioButton.on( 'mouseout', function() { this.removeClass( 'cke_btn_over' ); }, ratioButton ); } }, html : '<div>'+ '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.lockRatio + '" class="cke_btn_locked" id="' + btnLockSizesId + '" role="checkbox"><span class="cke_icon"></span><span class="cke_label">' + editor.lang.image.lockRatio + '</span></a>' + '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.resetSize + '" class="cke_btn_reset" id="' + btnResetSizeId + '" role="button"><span class="cke_label">' + editor.lang.image.resetSize + '</span></a>'+ '</div>' } ] }, { type : 'vbox', padding : 1, children : [ { id : 'cmbAlign', type : 'select', widths : [ '35%','65%' ], style : 'width:90px', label : editor.lang.common.align, 'default' : '', items : [ [ editor.lang.common.notSet , ''], [ editor.lang.common.alignLeft , 'left'], [ editor.lang.common.alignRight , 'right'] // Backward compatible with v2 on setup when specified as attribute value, // while these values are no more available as select options. // [ editor.lang.image.alignAbsBottom , 'absBottom'], // [ editor.lang.image.alignAbsMiddle , 'absMiddle'], // [ editor.lang.image.alignBaseline , 'baseline'], // [ editor.lang.image.alignTextTop , 'text-top'], // [ editor.lang.image.alignBottom , 'bottom'], // [ editor.lang.image.alignMiddle , 'middle'], // [ editor.lang.image.alignTop , 'top'] ], onChange : function() { updatePreview( this.getDialog() ); commitInternally.call( this, 'advanced:txtdlgGenStyle' ); }, setup : function( type, element ) { if ( type == IMAGE ) { var value = element.getStyle( 'float' ); switch( value ) { // Ignore those unrelated values. case 'inherit': case 'none': value = ''; } !value && ( value = ( element.getAttribute( 'align' ) || '' ).toLowerCase() ); this.setValue( value ); } }, commit : function( type, element, internalCommit ) { var value = this.getValue(); if ( type == IMAGE || type == PREVIEW ) { if ( value ) element.setStyle( 'float', value ); else element.removeStyle( 'float' ); if ( !internalCommit && type == IMAGE ) { value = ( element.getAttribute( 'align' ) || '' ).toLowerCase(); switch( value ) { // we should remove it only if it matches "left" or "right", // otherwise leave it intact. case 'left': case 'right': element.removeAttribute( 'align' ); } } } else if ( type == CLEANUP ) element.removeStyle( 'float' ); } } ] } ] }, { type : 'vbox', height : '250px', children : [ { type : 'html', id : 'htmlPreview', style : 'width:95%;', html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.common.preview ) +'<br>'+ '<div id="' + imagePreviewLoaderId + '" class="ImagePreviewLoader" style="display:none"><div class="loading"> </div></div>'+ '<div class="ImagePreviewBox"><table><tr><td>'+ '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="' + previewLinkId + '">'+ '<img id="' + previewImageId + '" alt="" /></a>' + ( editor.config.image_previewText ||'' ) + '</td></tr></table></div></div>' } ] } ] } ] }, { id : 'Link', hidden : true, label : editor.lang.link.title, padding : 0, elements : [ { id : 'txtUrl', type : 'text', label : editor.lang.common.url, style : 'width: 100%', 'default' : '', setup : function( type, element ) { if ( type == LINK ) { var href = element.data( 'cke-saved-href' ); if ( !href ) href = element.getAttribute( 'href' ); this.setValue( href ); } }, commit : function( type, element ) { if ( type == LINK ) { if ( this.getValue() || this.isChanged() ) { var url = decodeURI( this.getValue() ); element.data( 'cke-saved-href', url ); element.setAttribute( 'href', url ); if ( this.getValue() || !editor.config.image_removeLinkByEmptyURL ) this.getDialog().addLink = true; } } } }, { type : 'button', id : 'browse', filebrowser : { action : 'Browse', target: 'Link:txtUrl', url: editor.config.filebrowserImageBrowseLinkUrl }, style : 'float:right', hidden : false, label : editor.lang.common.browseServer }, { id : 'cmbTarget', type : 'select', label : editor.lang.common.target, 'default' : '', items : [ [ editor.lang.common.notSet , ''], [ editor.lang.common.targetNew , '_blank'], [ editor.lang.common.targetTop , '_top'], [ editor.lang.common.targetSelf , '_self'], [ editor.lang.common.targetParent , '_parent'] ], setup : function( type, element ) { if ( type == LINK ) this.setValue( element.getAttribute( 'target' ) || '' ); }, commit : function( type, element ) { if ( type == LINK ) { if ( this.getValue() || this.isChanged() ) element.setAttribute( 'target', this.getValue() ); } } } ] }, { id : 'Upload', hidden : false, filebrowser : 'uploadButton', label : editor.lang.image.upload, elements : [ { type : 'file', id : 'upload', label : editor.lang.image.btnUpload, style: 'height:40px', size : 38 }, { type : 'fileButton', id : 'uploadButton', filebrowser : 'info:txtUrl', label : editor.lang.image.btnUpload, 'for' : [ 'Upload', 'upload' ] } ] }, { id : 'advanced', label : editor.lang.common.advancedTab, elements : [ { type : 'hbox', widths : [ '50%', '25%', '25%' ], children : [ { type : 'text', id : 'linkId', label : editor.lang.common.id, setup : function( type, element ) { if ( type == IMAGE ) this.setValue( element.getAttribute( 'id' ) ); }, commit : function( type, element ) { if ( type == IMAGE ) { if ( this.getValue() || this.isChanged() ) element.setAttribute( 'id', this.getValue() ); } } }, { id : 'cmbLangDir', type : 'select', style : 'width : 100px;', label : editor.lang.common.langDir, 'default' : '', items : [ [ editor.lang.common.notSet, '' ], [ editor.lang.common.langDirLtr, 'ltr' ], [ editor.lang.common.langDirRtl, 'rtl' ] ], setup : function( type, element ) { if ( type == IMAGE ) this.setValue( element.getAttribute( 'dir' ) ); }, commit : function( type, element ) { if ( type == IMAGE ) { if ( this.getValue() || this.isChanged() ) element.setAttribute( 'dir', this.getValue() ); } } }, { type : 'text', id : 'txtLangCode', label : editor.lang.common.langCode, 'default' : '', setup : function( type, element ) { if ( type == IMAGE ) this.setValue( element.getAttribute( 'lang' ) ); }, commit : function( type, element ) { if ( type == IMAGE ) { if ( this.getValue() || this.isChanged() ) element.setAttribute( 'lang', this.getValue() ); } } } ] }, { type : 'text', id : 'txtGenLongDescr', label : editor.lang.common.longDescr, setup : function( type, element ) { if ( type == IMAGE ) this.setValue( element.getAttribute( 'longDesc' ) ); }, commit : function( type, element ) { if ( type == IMAGE ) { if ( this.getValue() || this.isChanged() ) element.setAttribute( 'longDesc', this.getValue() ); } } }, { type : 'hbox', widths : [ '50%', '50%' ], children : [ { type : 'text', id : 'txtGenClass', label : editor.lang.common.cssClass, 'default' : '', setup : function( type, element ) { if ( type == IMAGE ) this.setValue( element.getAttribute( 'class' ) ); }, commit : function( type, element ) { if ( type == IMAGE ) { if ( this.getValue() || this.isChanged() ) element.setAttribute( 'class', this.getValue() ); } } }, { type : 'text', id : 'txtGenTitle', label : editor.lang.common.advisoryTitle, 'default' : '', onChange : function() { updatePreview( this.getDialog() ); }, setup : function( type, element ) { if ( type == IMAGE ) this.setValue( element.getAttribute( 'title' ) ); }, commit : function( type, element ) { if ( type == IMAGE ) { if ( this.getValue() || this.isChanged() ) element.setAttribute( 'title', this.getValue() ); } else if ( type == PREVIEW ) { element.setAttribute( 'title', this.getValue() ); } else if ( type == CLEANUP ) { element.removeAttribute( 'title' ); } } } ] }, { type : 'text', id : 'txtdlgGenStyle', label : editor.lang.common.cssStyle, validate : CKEDITOR.dialog.validate.inlineStyle( editor.lang.common.invalidInlineStyle ), 'default' : '', setup : function( type, element ) { if ( type == IMAGE ) { var genStyle = element.getAttribute( 'style' ); if ( !genStyle && element.$.style.cssText ) genStyle = element.$.style.cssText; this.setValue( genStyle ); var height = element.$.style.height, width = element.$.style.width, aMatchH = ( height ? height : '' ).match( regexGetSize ), aMatchW = ( width ? width : '').match( regexGetSize ); this.attributesInStyle = { height : !!aMatchH, width : !!aMatchW }; } }, onChange : function () { commitInternally.call( this, [ 'info:cmbFloat', 'info:cmbAlign', 'info:txtVSpace', 'info:txtHSpace', 'info:txtBorder', 'info:txtWidth', 'info:txtHeight' ] ); updatePreview( this ); }, commit : function( type, element ) { if ( type == IMAGE && ( this.getValue() || this.isChanged() ) ) { element.setAttribute( 'style', this.getValue() ); } } } ] } ] }; }; CKEDITOR.dialog.add( 'image', function( editor ) { return imageDialog( editor, 'image' ); }); CKEDITOR.dialog.add( 'imagebutton', function( editor ) { return imageDialog( editor, 'imagebutton' ); });})();
做出的显示效果如下。
点击图片按钮显示图片上传界面
java中上传图片代码如下
@RequestMapping("imageUpload") public void imageUpload(HttpServletRequest request, HttpServletResponse response) { String DirectoryName = "upload/"; try { ImageUploadUtil.ckeditor(request, response, DirectoryName); } catch (Exception e) { logger.error(e.getMessage(), e); } }
import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.PrintWriter;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.log4j.Logger;import org.springframework.web.multipart.MultipartFile;import org.springframework.web.multipart.MultipartHttpServletRequest;import org.springframework.web.multipart.commons.CommonsMultipartResolver;/** * @ClassName: ImageUploadUtil * @Description: 图片上传工具类,包括ckeditor操作 * @author manman */public class ImageUploadUtil { private static Logger logger=Logger.getLogger(ImageUploadUtil.class); // 图片类型 private static List<String> fileTypes = new ArrayList<String>(); static { fileTypes.add(".jpg"); fileTypes.add(".jpeg"); fileTypes.add(".bmp"); fileTypes.add(".gif"); fileTypes.add(".png"); } public static String upload(HttpServletRequest request, String DirectoryName) throws IllegalStateException, IOException { // 创建一个通用的多部分解析器 CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver( request.getSession().getServletContext()); // 图片名称 String fileName = null; // 判断 request 是否有文件上传,即多部分请求 if (multipartResolver.isMultipart(request)) { // 转换成多部分request MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request; // 取得request中的所有文件名 Iterator<String> iter = multiRequest.getFileNames(); while (iter.hasNext()) { // 记录上传过程起始时的时间,用来计算上传时间 // int pre = (int) System.currentTimeMillis(); // 取得上传文件 MultipartFile file = multiRequest.getFile(iter.next()); if (file != null) { // 取得当前上传文件的文件名称 String myFileName = file.getOriginalFilename(); // 如果名称不为“”,说明该文件存在,否则说明该文件不存在 if (myFileName.trim() != "") { // 获得图片的原始名称 String originalFilename = file.getOriginalFilename(); // 获得图片后缀名称,如果后缀不为图片格式,则不上传 String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase(); if (!fileTypes.contains(suffix)) { continue; } // 获得上传路径的绝对路径地址(/upload)--> String realPath = request.getSession().getServletContext().getRealPath("/" + DirectoryName); // 如果路径不存在,则创建该路径 File realPathDirectory = new File(realPath); if (realPathDirectory == null || !realPathDirectory.exists()) { realPathDirectory.mkdirs(); } // 重命名上传后的文件名 111112323.jpg fileName = DateUtil.getCurrentDate("yyyyMMddHHmmss")+ suffix; // 定义上传路径 .../upload/111112323.jpg File uploadFile = new File(realPathDirectory + "\\" + fileName); logger.error("图片的路径:"+uploadFile); file.transferTo(uploadFile); } } // 记录上传该文件后的时间 // int finaltime = (int) System.currentTimeMillis(); // System.out.println(finaltime - pre); } } return fileName; } /** * ckeditor文件上传功能,回调,传回图片路径,实现预览效果。 * * @Title ckeditor * @param request * @param response * @param DirectoryName * 文件上传目录:比如upload(无需带前面的/) upload/.. * @throws IOException */ public static void ckeditor(HttpServletRequest request, HttpServletResponse response, String DirectoryName) throws IOException { String fileName = upload(request, DirectoryName); // 结合ckeditor功能 // imageContextPath为图片在服务器地址,如upload/123.jpg,非绝对路径 String imageContextPath = request.getContextPath() + "/" + DirectoryName + "/" + fileName; response.setContentType("text/html;charset=UTF-8"); String callback = request.getParameter("CKEditorFuncNum"); PrintWriter out = response.getWriter(); out.println("<script type=\"text/javascript\">"); out.println("window.parent.CKEDITOR.tools.callFunction(" + callback + ",'" + imageContextPath + "',''" + ")"); out.println("</script>"); out.flush(); out.close(); }}
阅读全文
0 0
- java 项目整合ckeditor实现图文混排
- 图文混排实现
- TextKit实现图文混排
- CoreText实现图文混排
- TextKit实现图文混排
- CoreText实现图文混排
- CoreText实现图文混排
- CoreText实现图文混排
- webView实现图文混排
- SpannableStringBuilder实现图文混排
- iOS 实现图文混排
- CoreText实现图文混排
- CoreText实现图文混排
- CoreText 实现图文混排
- EditTexts实现图文混排
- TextKit实现图文混排
- CoreText 实现图文混排
- SWIFT实现图文混排
- 中文字符串长度问题:strlen和mb_strlen
- 一步步实现:JPA的基本增删改查CRUD(jpa基于hibernate)
- npm 的rollbackFailedOptional以及node.js npm fetchmetadata 卡住错误解决~
- hdu 6058 Kanade's sum
- POJ 1088 滑雪 (DP)
- java 项目整合ckeditor实现图文混排
- 广告行业中富媒体的概念
- lr学习笔记--录制过程自动设置检查点检查该动作成功的标志相当于断言web_reg_find
- Mac 命令行下 ll命令
- OpenCV学习(6) 文件和Mat之间的数据交换
- sql函数concat的用法
- Java开发环境搭建(进阶配置一 ——Maven)
- mfc 字符总结,char* cString相互转换
- 函数传参原理