欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實現(xiàn)在線編輯預(yù)覽office文檔詳解

 更新時間:2024年01月14日 16:23:45   作者:愛吃牛肉的大老虎  
PageOffice是一款在線的office編輯軟件,幫助Web應(yīng)用系統(tǒng)或Web網(wǎng)站實現(xiàn)用戶在線編輯Word、Excel、PowerPoint文檔,下面我們就來看看如何使用Java實現(xiàn)在線預(yù)覽office吧

1 在線編輯

1.1 PageOffice簡介

PageOffice是一款在線的office編輯軟件,幫助Web應(yīng)用系統(tǒng)或Web網(wǎng)站實現(xiàn)用戶在線編輯Word、Excel、PowerPoint文檔??梢酝昝缹崿F(xiàn)在線公文流轉(zhuǎn),領(lǐng)導批閱,蓋章??梢越o文件添加水印,在線安全預(yù)覽防止用戶下載和復制文件等

1.2 前端項目

由于pageoffice瀏覽器是ie內(nèi)核,vue3不兼容ie。所以需要把頁面放在后端

1.2.1 配置

在 vue.config.js 中配置代理

devServer: {
        proxy: {
        '/api': {
          target: 'http://localhost:8081/samples-springboot-back', //"/api"對應(yīng)后端項目"http://localhost:8081/samples-springboot-back"地址 
          ws: true,
          changeOrigin: true, // 允許跨域
          pathRewrite: {
           '^/api': ''   // 標識替換,使用 '/api' 代替真實的接口地址
          }
        }
      }
    }

1.2.2 頁面部分

在index.html頁面引用后端項目(samples-springboot-back)根目錄下的pageoffice.js

<script type="text/javascript" src="http://localhost:8081/samples-springboot-back/pageoffice.js"></script>

在index.vue頁面添加一個按鈕,調(diào)用POBrowser.openWindowModeless請求后端。http://localhost:8081/springboot-pageoffice-demo/SimpleWord/Word2 是后端打開文件的controller

POBrowser.openWindowModeless('http://localhost:8081/springboot-pageoffice-demo/SimpleWord/Word2', 'width=1150px;height=900px;');

在Word.vue頁面created中通過axios請求后臺獲取pageoffice控件(注意:后臺返回string字符串,前端需要使用v-html解析)

這里給后臺發(fā)請求的是axios,如果需要添加token可以在main.js中配置攔截器給請求添加token

Word.vue頁面,可以直接復制后修改url

<template>
 <div class="Word">
  <div style="height: 800px; width: auto" v-html="poHtmlCode" />
 </div>
</template>
<script>
const axios = require("axios");
export default {
  name: "Word",
  data() {
    return {
      poHtmlCode: "",
    };
  },
  created: function () {
    axios
      .post("/api/SimpleWord/Word")
      .then((response) => {
        this.poHtmlCode = response.data;
      })
      .catch(function (err) {
        console.log(err);
      });
  },
  methods: {
    //控件中的一些常用方法都在這里調(diào)用,比如保存,打印等等
    /**
     * Save()方法是/api/SimpleWord/Word這個后臺controller中PageOfficeCtrl控件通過poCtrl.addCustomToolButton定義的方法,除了保存還有另存到本地、打印等功能。
     */
    Save() {
      document.getElementById("PageOfficeCtrl1").WebSave();
    }
  },
  mounted: function () {
    // 將PageOffice控件中的方法通過mounted掛載到window對象上,只有掛載后才能被vue組件識別
    window.Save = this.Save;
  },
};
</script>

1.3 后端項目

1.3.1 pom.xml

<dependency>
    <groupId>com.zhuozhengsoft</groupId>
    <artifactId>pageoffice</artifactId>
    <version>5.4.0.3</version>
</dependency>

1.3.2 添加配置

在啟動類中配置servlet bean,poSysPath 是在 properites 中配置的磁盤路徑(注意:pageoffice的poserver.zz等這些請求不要攔截,get和post請求都放出來)

@Bean
public ServletRegistrationBean pageofficeRegistrationBean() {
    com.zhuozhengsoft.pageoffice.poserver.Server poserver = new com.zhuozhengsoft.pageoffice.poserver.Server();
    poserver.setSysPath(poSysPath);//設(shè)置PageOffice注冊成功后,license.lic文件存放的目錄
    ServletRegistrationBean srb = new ServletRegistrationBean(poserver);
    srb.addUrlMappings("/poserver.zz");
    srb.addUrlMappings("/posetup.exe");
    srb.addUrlMappings("/pageoffice.js");
    srb.addUrlMappings("/jquery.min.js");
    srb.addUrlMappings("/pobstyle.css");
    srb.addUrlMappings("/sealsetup.exe");
    return srb;
}

1.3.3 controller

打開文件的controller(webopen第一個參數(shù)是當前文件的磁盤路徑,磁盤路徑必須反向雙斜杠)。

setServerPage和setSaveFilePage中的api是前端代理,前后端分離項目必須配置代理

@RestController
@RequestMapping(value = "/SimpleWord")
public class SimpleWordController { 
        @RequestMapping(value="/Word")
        public String showWord(HttpServletRequest request) {
 
            PageOfficeCtrl poCtrl = new PageOfficeCtrl(request);
            poCtrl.setServerPage("/api/poserver.zz");//設(shè)置服務(wù)頁面
            poCtrl.addCustomToolButton("保存", "Save", 1);
 
            poCtrl.setSaveFilePage("/api/SimpleWord/save");//設(shè)置保存方法的url
            //打開word
            poCtrl.webOpen("D:\\doc\\test.docx", OpenModeType.docNormalEdit, "張三");
            return  poCtrl.getHtmlCode("PageOfficeCtrl1");
        }
 
        @RequestMapping("save")
        public void save(HttpServletRequest request, HttpServletResponse response) { 
            FileSaver fs = new FileSaver(request, response);
            fs.saveToFile("D:\\doc\\" + fs.getFileName());
            fs.close();
        } 
    }

2 在線預(yù)覽

2.1 引言

最近遇到了文件預(yù)覽的需求,但一搜索發(fā)現(xiàn),這還不是一個簡單的功能。于是又去查詢了很多資料,調(diào)研了一些方案,也踩了好多坑。最后總結(jié)方案如下:

花錢解決(使用市面上現(xiàn)有的文件預(yù)覽服務(wù))

微軟,google,阿里云 IMM,XDOC,Office Web 365,wps開放平臺

前端方案

pptx的預(yù)覽方案,pdf的預(yù)覽方案,docx的預(yù)覽方案,xlsx(excel)的預(yù)覽方案

服務(wù)端方案

openOffice,kkFileView,onlyOffice

2.2 市面上現(xiàn)有的文件預(yù)覽服務(wù)

2.2.1 微軟

docx,pptx,xlsx可以說是office三件套,那自然得看一下微軟官方提供的文件預(yù)覽服務(wù)。使用方法特別簡單,只需要將文件鏈接,拼接到參數(shù)后面即可。

記得encodeURL

https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(url)}

對于docx,pptx,xlsx都有較好的支持,pdf不行。

還有一個坑點是:這個服務(wù)是否穩(wěn)定,有什么限制,是否收費,都查不到一個定論。在office官方網(wǎng)站上甚至找不到介紹這個東西的地方。

目前只能找到一個Q&A:

微軟官方人員回答表示:

翻譯翻譯,就是:幾乎永久使用,沒有收費計劃,不會存儲預(yù)覽的文件數(shù)據(jù),限制文件10MB,建議用于 查看互聯(lián)網(wǎng)上公開的文件。

但經(jīng)過某些用戶測試發(fā)現(xiàn),使用了微軟的文件預(yù)覽服務(wù),然后刪除了文件地址,仍然可訪問,但過一段時間才會失效。

2.2.2 Google Drive查看器

接入簡單,同 Office Web Viewer,只需要把 src 改為https://drive.google.com/viewer?url=${encodeURIComponent(url)}即可。

限制25MB,支持以下格式:

測試效果,支持docx,pptx,xlsx,pdf預(yù)覽,但pptx預(yù)覽的效果不如微軟,沒有動畫效果,樣式有小部分會錯亂。

2.2.3 阿里云 IMM

官方文檔如下

付費使用

2.2.4 XDOC 文檔預(yù)覽

說了一些大廠的,在介紹一些其他的,需要自行分辨

2.2.5 Office Web 365

需要注意的是,雖然名字很像office,但我們看網(wǎng)頁的Copyright可以發(fā)現(xiàn),其實是一個西安的公司,不是微軟,但畢竟也提供了文件預(yù)覽的服務(wù)

官網(wǎng)地址:www.officeweb365.com/

2.2.6 WPS開放平臺

官方地址:solution.wps.cn

付費使用,價格如下:

2.3 前端處理方案

2.3.1 pptx的預(yù)覽方案

先查一下有沒有現(xiàn)成的輪子,目前 pptx 的開源預(yù)覽方案能找到的只有這個:github.com/g21589/PPTX…[6] 。但已經(jīng)六七年沒有更新,也沒有維護,筆者使用的時候發(fā)現(xiàn)有很多兼容性問題。

簡單來說就是,沒有。

對于這種情況,我們可以自行解析,主要步驟如下:

  • 查詢pptx的國際標準
  • 解析pptx文件
  • 渲染成html或者canvas進行展示

我們先去找一下pptx的國際標準

先解釋下什么是officeopenxml:

Office OpenXML,也稱為OpenXML或OOXML,是一種基于XML的辦公文檔格式,包括文字處理文檔、電子表格、演示文稿以及圖表、圖表、形狀和其他圖形材料。該規(guī)范由微軟開發(fā),并于2006年被ECMA國際采用為ECMA-376。第二個版本于2008年12月發(fā)布,第三個版本于2011年6月發(fā)布。該規(guī)范已被ISO和IEC采用為ISO/IEC 29500。

雖然Microsoft繼續(xù)支持較舊的二進制格式(.doc、.xls和.ppt),但OOXML現(xiàn)在是所有Microsoft Office文檔(.docx、.xlsx和.pptx)的默認格式。

由此可見,Office OpenXML由微軟開發(fā),目前已經(jīng)是國際標準。

接下來我們看一下pptx里面有哪些內(nèi)容,具體可以看pptx的官方標準:officeopenxml-pptx[8]

PresentationML或.pptx文件是一個zip文件,其中包含許多“部分”(通常是UTF-8或UTF-16編碼)或XML文件。該包還可能包含其他媒體文件,例如圖像。該結(jié)構(gòu)根據(jù) OOXML 標準 ECMA-376 第 2 部分中概述的開放打包約定進行組織。

根據(jù)國際標準,我們知道,pptx文件本質(zhì)就是一個zip文件,其中包含許多部分:

部件的數(shù)量和類型將根據(jù)演示文稿中的內(nèi)容而有所不同,但始終會有一個 [Content_Types].xml、一個或多個關(guān)系 (.rels) 部件和一個演示文稿部件(演示文稿.xml),它位于 ppt 文件夾中,用于Microsoft Powerpoint 文件。通常,還將至少有一個幻燈片部件,以及一張母版幻燈片和一張版式幻燈片,從中形成幻燈片。

那么js如何讀取zip呢?

找到一個工具: www.npmjs.com

于是我們可以開始嘗試解析pptx了。

import JSZip from 'jszip'
// 加載pptx數(shù)據(jù)
const zip = await JSZip.loadAsync(pptxData)

解析[Content_Types].xml

每個pptx必然會有一個 [Content_Types].xml。此文件包含包中部件的所有內(nèi)容類型的列表。每個部件及其類型都必須列在 [Content_Types].xml 中。通過它里面的內(nèi)容,可以解析其他的文件數(shù)據(jù)

const filesInfo = await getContentTypes(zip)

???????async function getContentTypes(zip: JSZip) {
    const ContentTypesJson = await readXmlFile(zip, '[Content_Types].xml')
    const subObj = ContentTypesJson['Types']['Override']
    const slidesLocArray = []
    const slideLayoutsLocArray = []
    for (let i = 0; i < subObj.length; i++) {
      switch (subObj[i]['attrs']['ContentType']) {
        case 'application/vnd.openxmlformats-officedocument.presentationml.slide+xml':
          slidesLocArray.push(subObj[i]['attrs']['PartName'].substr(1))
          break
        case 'application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml':
          slideLayoutsLocArray.push(subObj[i]['attrs']['PartName'].substr(1))
          break
        default:
      }
    }
    return {
      slides: slidesLocArray,
      slideLayouts: slideLayoutsLocArray,
    }
  }

解析演示文稿

先獲取ppt目錄下的presentation.xml演示文稿的大小

由于演示文稿是xml格式,要真正的讀取內(nèi)容需要執(zhí)行 readXmlFile

const slideSize = await getSlideSize(zip)
 async function getSlideSize(zip: JSZip) {
    const content = await readXmlFile(zip, 'ppt/presentation.xml')
    const sldSzAttrs = content['p:presentation']['p:sldSz']['attrs']
    return {
      width: (parseInt(sldSzAttrs['cx']) * 96) / 914400,
      height: (parseInt(sldSzAttrs['cy']) * 96) / 914400,
    }
  }

加載主題

根據(jù) officeopenxml的標準解釋

每個包都包含一個關(guān)系部件,用于定義其他部件之間的關(guān)系以及與包外部資源的關(guān)系。這樣可以將關(guān)系與內(nèi)容分開,并且可以輕松地更改關(guān)系,而無需更改引用目標的源。

除了包的關(guān)系部分之外,作為一個或多個關(guān)系源的每個部件都有自己的關(guān)系部分。每個這樣的關(guān)系部件都可以在部件的_rels子文件夾中找到,并通過在部件名稱后附加“.rels”來命名。

其中主題的相關(guān)信息就在ppt/_rels/presentation.xml.rels中

  async function loadTheme(zip: JSZip) {
    const preResContent = await readXmlFile(
      zip,
      'ppt/_rels/presentation.xml.rels',
    )
    const relationshipArray = preResContent['Relationships']['Relationship']
    let themeURI
    if (relationshipArray.constructor === Array) {
      for (let i = 0; i < relationshipArray.length; i++) {
        if (
          relationshipArray[i]['attrs']['Type'] ===
          'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme'
        ) {
          themeURI = relationshipArray[i]['attrs']['Target']
          break
        }
      }
    } else if (
      relationshipArray['attrs']['Type'] ===
      'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme'
    ) {
      themeURI = relationshipArray['attrs']['Target']
    }

    if (themeURI === undefined) {
      throw Error("Can't open theme file.")
    }

???????    return readXmlFile(zip, 'ppt/' + themeURI)
  }

2.3.2 pdf的預(yù)覽方案

2.3.2.1 iframe和embed

pdf 比較特別,一般的瀏覽器默認支持預(yù)覽pdf。因此,我們可以使用瀏覽器的能力:<iframe src="viewFileUrl" />
但這樣就完全依賴瀏覽器,對PDF的展示,交互,是否支持全看瀏覽器的能力,且不同的瀏覽器展示和交互往往不同,如果需要統(tǒng)一的話,最好還是嘗試其他方案。

embed的解析方式也是一樣,這里不舉例子了

2.3.2.2 pdfjs

由mozilla出品,就是我們常見的MDN的老大。而且目前 火狐瀏覽器 使用的 PDF 預(yù)覽就是采用這個,我們可以用火狐瀏覽器打開pdf文件,查看瀏覽器使用的js就能發(fā)現(xiàn)

需要注意的是,最新版 pdf.js 限制了 node 版本,需要大于等于18

如果你項目node版本小于這個情況,可能會無法使用。

具體使用情況如下:

import * as pdfjs from 'pdfjs-dist'
import * as pdfjsWorker from 'pdfjs-dist/build/pdf.work.entry'

interface Viewport {
  width: number
  height: number
  viewBox: Array<number>
}

interface RenderContext {
  canvasContext: CanvasRenderingContext2D | null
  transform: Array<number>
  viewport: Viewport
}

interface PDFPageProxy {
  pageNumber: number
  getViewport: () => Viewport
  render: (options: RenderContext) => void
}

interface PDFDocumentProxy {
  numPages: number
  getPage: (x: number) => Promise<PDFPageProxy>
}

class PdfPreview {
  private pdfDoc: PDFDocumentProxy | undefined
  pageNumber: number
  total: number
  dom: HTMLElement
  pdf: string | ArrayBuffer
  constructor(pdf: string | ArrayBuffer, dom: HTMLElement | undefined) {
    this.pageNumber = 1
    this.total = 0
    this.pdfDoc = undefined
    this.pdf = pdf
    this.dom = dom ? dom : document.body
  }
  private getPdfPage = (number: number) => {
    return new Promise((resolve, reject) => {
      if (this.pdfDoc) {
        this.pdfDoc.getPage(number).then((page: PDFPageProxy) => {
          const viewport = page.getViewport()
          const canvas = document.createElement('canvas')
          this.dom.appendChild(canvas)
          const context = canvas.getContext('2d')
          const [_, __, width, height] = viewport.viewBox
          canvas.width = width
          canvas.height = height
          viewport.width = width
          viewport.height = height
          canvas.style.width = Math.floor(viewport.width) + 'px'
          canvas.style.height = Math.floor(viewport.height) + 'px'
          const renderContext = {
            canvasContext: context,
            viewport: viewport,
            transform: [1, 0, 0, -1, 0, viewport.height],
          }
          page.render(renderContext)
          resolve({ success: true, data: page })
        })
      } else {
        reject({ success: false, data: null, message: 'pdfDoc is undefined' })
      }
    })
  }
  pdfPreview = () => {
      window.pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker
      window.pdfjsLib
        .getDocument(this.pdf)
        .promise.then(async (doc: PDFDocumentProxy) => {
          this.pdfDoc = doc
          this.total = doc.numPages
          for (let i = 1; i <= this.total; i++) {
            await this.getPdfPage(i)
          }
    })
  }
  prevPage = () => {
    if (this.pageNumber > 1) {
      this.pageNumber -= 1
    } else {
      this.pageNumber = 1
    }
    this.getPdfPage(this.pageNumber)
  }
  nextPage = () => {
    if (this.pageNumber < this.total) {
      this.pageNumber += 1
    } else {
      this.pageNumber = this.total
    }
    this.getPdfPage(this.pageNumber)
  }
}

const createReader = (file: File): Promise<string | ArrayBuffer | null> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = () => {
      resolve(reader.result)
    }
    reader.onerror = (error) => {
      reject(error)
    }
    reader.onabort = (abort) => {
      reject(abort)
    }
  })
}

export const renderPdf = async (
  file: File,
  dom?: HTMLElement,
): Promise<void> => {
  try {
    if (typeof window !== 'undefined') {
      const pdf = await createReader(file)
      if (pdf) {
        const PDF = new PdfPreview(pdf, dom)
        PDF.pdfPreview()
      }
    }
  } catch (error) {
    console.log('renderPdf', error)
  }
}

2.3.3 docx的預(yù)覽方案

我們可以去查看docx的國際標準,去解析文件格式,渲染成html和canvas,不過比較好的是,已經(jīng)有人這么做了,還開源了

使用方法如下:

import { renderAsync } from 'docx-preview'

interface DocxOptions {
  bodyContainer?: HTMLElement | null
  styleContainer?: HTMLElement
  buffer: Blob
  docxOptions?: Partial<Record<string, string | boolean>>
}

export const renderDocx = (options: DocxOptions): Promise<void> | undefined => {
  if (typeof window !== 'undefined') {
    const { bodyContainer, styleContainer, buffer, docxOptions = {} } = options
    const defaultOptions = {
      className: 'docx',
      ignoreLastRenderedPageBreak: false,
    }
    const configuration = Object.assign({}, defaultOptions, docxOptions)
    if (bodyContainer) {
      return renderAsync(buffer, bodyContainer, styleContainer, configuration)
    } else {
      const contain = document.createElement('div')
      document.body.appendChild(contain)
      return renderAsync(buffer, contain, styleContainer, configuration)
    }
  }
}

2.3.4 前端預(yù)覽方案總結(jié)

我們對以上找到的優(yōu)秀的解決方案,進行改進和總結(jié),并封裝成一個web components組件:preview組件

為什么是web components組件?

因為它跟框架無關(guān),可以在任何框架中使用,且使用起來跟原生的div標簽一樣方便。并編寫使用文檔: preview組件文檔, 文檔支持交互體驗。

目前docx,pdf,xlsx預(yù)覽基本可以了,都是最好的方案。pptx預(yù)覽效果不太好,因為需要自行解析。

2.4 服務(wù)端預(yù)覽方案

2.4.1 openOffice

由于瀏覽器不能直接打開 docx,pptx,xlsx 等格式文件,但可以直接打開pdf和圖片,因此,我們可以換一個思路,用服務(wù)端去轉(zhuǎn)換下文件的格式,轉(zhuǎn)換成瀏覽器能識別的格式,然后再讓瀏覽器打開,這不就OK了嗎,甚至不需要前端處理了。

我們可以借助openOffice的能力,先介紹一下openOffice:

Apache OpenOffice是領(lǐng)先的開源辦公軟件套件,用于文字處理,電子表格,演示文稿,圖形,數(shù)據(jù)庫等。它有多種語言版本,適用于所有常用計算機。它以國際開放標準格式存儲您的所有數(shù)據(jù),還可以從其他常見的辦公軟件包中讀取和寫入文件。它可以出于任何目的完全免費下載和使用。

官網(wǎng)如下:www.openoffice.org

完整示例如下:

package org.example;

import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeManager;

import java.io.File;

public class OfficeUtil {

    private static OfficeManager officeManager;
    private static int port[] = {8100};

    /**
     * start openOffice service.
     */
    public static void startService() {
        DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
        try {
            System.out.println("準備啟動office轉(zhuǎn)換服務(wù)....");
            configuration.setOfficeHome("這里的路徑一般為C:\\Program Files (x86)\\OpenOffice 4的bin目錄");
            configuration.setPortNumbers(port); // 設(shè)置轉(zhuǎn)換端口,默認為8100
            configuration.setTaskExecutionTimeout(1000 * 60 * 30L);// 設(shè)置任務(wù)執(zhí)行超時為30分鐘
            configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);// 設(shè)置任務(wù)隊列超時為24小時
            officeManager = configuration.buildOfficeManager();
            officeManager.start(); // 啟動服務(wù)
            System.out.println("office轉(zhuǎn)換服務(wù)啟動成功!");
        } catch (Exception e) {
            System.out.println("office轉(zhuǎn)換服務(wù)啟動失敗!詳細信息:" + e);
        }
    }

    /**
     * stop openOffice service.
     */
    public static void stopService() {
        System.out.println("準備關(guān)閉office轉(zhuǎn)換服務(wù)....");
        if (officeManager != null) {
            officeManager.stop();
        }
        System.out.println("office轉(zhuǎn)換服務(wù)關(guān)閉成功!");
    }

    public static void convertToPDF(String inputFile, String outputFile) {
        startService();
        System.out.println("進行文檔轉(zhuǎn)換轉(zhuǎn)換:" + inputFile + " --> " + outputFile);
        OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
        converter.convert(new File(inputFile), new File(outputFile));
        stopService();
    }

    public static void main(String[] args) {
        convertToPDF("/Users/koolearn/Desktop/asdf.docx", "/Users/koolearn/Desktop/adsf.pdf");
    }
}

2.4.2 kkFileView

支持的文件預(yù)覽格式非常豐富圖片

安裝下libreoffice :

kkFileView明確要求的額外依賴 libreoffice,否則無法啟動

啟動項目

找到主文件,主函數(shù)mian,即可執(zhí)行

2.4.3 onlyOffice

官網(wǎng)地址:https://www.onlyoffice.com/zh

開發(fā)者版本和社區(qū)版免費,企業(yè)版付費:www.onlyoffice.com/zh/docs-ent

預(yù)覽的文件種類沒有kkFileView多,但對office三件套有很好的支持,甚至支持多人編輯。

以上就是Java實現(xiàn)在線編輯預(yù)覽office文檔詳解的詳細內(nèi)容,更多關(guān)于Java在線預(yù)覽office的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring Cloud Config實現(xiàn)分布式配置中心

    Spring Cloud Config實現(xiàn)分布式配置中心

    這篇文章主要介紹了Spring Cloud Config實現(xiàn)分布式配置中心,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • Java多線程深入理解

    Java多線程深入理解

    這篇文章主要介紹了java多線程編程實例,分享了幾則多線程的實例代碼,具有一定參考價值,加深多線程編程的理解還是很有幫助的,需要的朋友可以參考下
    2021-07-07
  • Spring源碼完美導入IDEA的過程

    Spring源碼完美導入IDEA的過程

    正值春節(jié)假期,小伙伴私信我idea導入spring源碼的過程,今天抽空給大家整理一篇教程幫助大家學習Spring源碼完美導入IDEA的詳細過程,感興趣的朋友一起看看吧
    2022-02-02
  • maven依賴包加載緩慢的原因以及解決方案

    maven依賴包加載緩慢的原因以及解決方案

    這篇文章主要介紹了maven依賴包加載緩慢的原因以及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java NIO異步文件通道原理及用法解析

    Java NIO異步文件通道原理及用法解析

    這篇文章主要介紹了Java NIO異步文件通道原理及用法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • MyBatisPlus中使用or()和and()遇到的問題及細節(jié)處理

    MyBatisPlus中使用or()和and()遇到的問題及細節(jié)處理

    這篇文章主要介紹了MyBatisPlus中使用or()和and()遇到的問題,本文通過多種寫法實例代碼相結(jié)合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • springboot+mybaties項目中掃描不到@mapper注解的解決方法

    springboot+mybaties項目中掃描不到@mapper注解的解決方法

    本文主要介紹了springboot+mybaties項目中掃描不到@mapper注解的解決方法,該報錯表明掃描不到Mapper層,具有一定的參考價值,感興趣的可以了解一下
    2024-05-05
  • java實現(xiàn)簡單的學生信息管理系統(tǒng)代碼實例

    java實現(xiàn)簡單的學生信息管理系統(tǒng)代碼實例

    這篇文章主要介紹了java實現(xiàn)簡單的學生信息管理系統(tǒng),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • SpringMVC處理Form表單實例

    SpringMVC處理Form表單實例

    這篇文章主要介紹了使用SpringMVC處理Form表單實例,非常具有參考借鑒價值,感興趣的朋友一起學習吧
    2016-10-10
  • java自帶命令行工具jmap、jhat與jinfo的使用實例代碼詳解

    java自帶命令行工具jmap、jhat與jinfo的使用實例代碼詳解

    本篇文章主要通過代碼實例對java自帶命令行工具jmap、jhat與jinfo的使用做出了詳解,需要的朋友可以參考下
    2017-04-04

最新評論